Остановка каждого task отдельным token

135
15 января 2020, 21:20

Пытаюсь разобраться с асинхронной работой в C#, создал форму с прогресбарами, и для заполнения каждого создал отдельный task. Создал массив токенов, для остановки отдельного таска, но проблема в том, что при нажатии верхней кнопки останавливаются все таски, а на другие кнопки реакции нет, хотя отработка события происходит и в списке токенов меняется значение IsCancelationRequest.

    public partial class Form1 : Form
{
    Random random = new Random();
    List<Task> tasks = new List<Task>();
    List<ProgressBar> bars = new List<ProgressBar>();
    List<Button> btns = new List<Button>();
    List<CancellationTokenSource> tSources = new List<CancellationTokenSource>();
    List<CancellationToken> tokens = new List<CancellationToken>();
    public Form1()
    {
        InitializeComponent();
        foreach (Control cntrl in this.Controls)
        {
            if (cntrl is ProgressBar)
            {
                bars.Add(cntrl as ProgressBar);
                tSources.Add(new CancellationTokenSource());
                tokens.Add(tSources.Last().Token);
                tasks.Add(new Task(() => Progress(cntrl as ProgressBar, 
                    tokens.Last())));
            }
        }
        foreach (Control cntrl in this.Controls)
        {
            if (cntrl is Button)
            {
                if (cntrl.Name != "StartButton")
                {
                    btns.Add(cntrl as Button);
                    cntrl.Click += Cntrl_Click;
                }
            }
        }
    }
    private void Cntrl_Click(object sender, EventArgs e)
    {
        int i = btns.IndexOf(sender as Button);
        tSources[i].Cancel();
    }
    public void Progress(ProgressBar progress, CancellationToken token)
    {
        for (int i = 0; i <= 100; i++)
        {
            if (token.IsCancellationRequested)
                return;
            if (progress.InvokeRequired)
                progress.Invoke(new Action(() => progress.Value = i));
            else
                progress.Value = i;
            Thread.Sleep(random.Next(1000));
        }
    }
    private void Button1_Click(object sender, EventArgs e)
    {
        foreach (Task t in tasks)
            t.Start();
    }
}

}

Я так понимаю, что неправильно передаю токен в таск, но не могу понять где.

READ ALSO
Приложение на asp.net mvc + angular 7

Приложение на asp.net mvc + angular 7

Начинаю изучать angularСкачал node

143
использование ConcurentBag при работе с БД

использование ConcurentBag при работе с БД

Как можно использовать ConcurrentBag при работе с БД? и в каких случаях это нужноБольшинство примеров рассмотрены с добавлением string/int значений

143
Как убрать квадратики по рамке datagridview в Metro Framework?

Как убрать квадратики по рамке datagridview в Metro Framework?

Как убрать в datagridview tabs вот эти квадратики мини рамка сколько гуглил смотрел документацию ничего не нашел

124
Запрет наследования метода класса в PHP

Запрет наследования метода класса в PHP

Для запрета наследования целого класса в PHP есть ключевое слово final:

147