c# как распаралелить задачу, чтобы она выполнялась три раза

Я создаю циклом задачи, в результате я должен получить 1 скачалась 2 скачалась 3 скачалась Но вместо этого я получаю 1 скачалась 1 скачалась 1 скачалась То есть данные в этих запущенных задачах не меняются. Хочу получить результат как у многих программ, запуск в потоках, то есть одна задача выполняется много раз и при это разный результат

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Leaf.xNet;
using System.Threading;
using System.IO;

namespace Создание_потоков
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private string Random_name()
        {
            string image = "";
            var r = new Random();
            while (image.Length < 12)
            {
                Char c = (char)r.Next(33, 125);
                if (Char.IsLetterOrDigit(c))
                    image += c;
            }
            return image;
        }
        void Download_Image()
        {
                string image_name = Random_name();
                HttpRequest request = new HttpRequest();
                request.KeepAlive = true;
                request.UserAgentRandomize();
                var bytes = request.Get("https://thiscatdoesnotexist.com/").ToBytes();
                File.WriteAllBytes(image_name + ".jpeg", bytes);
                Invoke((MethodInvoker)delegate { textBox1.AppendText(image_name + " Скачалась" + Environment.NewLine); });
        }
        private async void button1_Click(object sender, EventArgs e)
        {
            List<Task> tasks = new List<Task>(); // список задач
            for (int i = 0; i < 3; i++) // Добавляем циклом задачи, но выполняется как будто один развыполнилась, данные не меняются
            {

                tasks.Add(Task.Run(() => { Download_Image(); }));
            }
            await Task.WhenAll(tasks); // ждем всё
        }
    }
}

Ответы (1 шт):

Автор решения: aepot

Вы просто запутались в этих тасках. Все намного проще. Единственное, чтобы обновлять содержимое текстбокса из стороннего потока, я стащил один метод отсюда.

private Random rndGen = new Random();

private string Random_name()
{
    string image = "";
    while (image.Length < 12)
    {
        lock(rndGen)
        {
            Char c = (char)rndGen.Next(33, 125);
        }
        if (Char.IsLetterOrDigit(c))
            image += c;
    }
    return image;
}

private void Download_Image()
{
    string image_name = Random_name(); // избегайте глобальных переменных при многопоточной работе
    HttpRequest request = new HttpRequest();
    request.KeepAlive = true;
    request.UserAgentRandomize();
    var bytes = request.Get("https://thiscatdoesnotexist.com/").ToBytes();
    File.WriteAllBytes(image_name + ".jpeg", bytes);
    AppendTextBox(image_name + " Скачалась" + Environment.NewLine);
}

private void AppendTextBox(string value)
{
    if (InvokeRequired)
    {
        this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
        return;
    }
    textBox1.Text += value;
}

// async обработчик, чтобы не морозить интерфейс, пока работают таски
// хотя можно было бы и без async и не ждать
private async void button1_Click(object sender, EventArgs e)
{
    List<Task> tasks = new List<Task>(); // список задач
    for (int i = 0; i < 3; i++)
    { 
        tasks.Add(Task.Run(Download_Image)); // добавляем задачу
    }
    await Task.WhenAll(tasks); // ждем все
    textBox1.Text += "Всё скачалось" + Environment.NewLine;
}
→ Ссылка