как правильно отменить несколько задач в c#

У меня кнопка вот нерестится 4 задачи. Та же кнопка изменяется на кнопку отмены, и нажатие на нее должно отменить все 4 задачи. Должен ли я передать тот же токен отмены всем 4 задачам и опросить их на том же токене для IsCancelRequested ? Я смущен после чтения документа msdn на createlinkedtokensource. Как это обычно делается ? спасибо

Обновление: Задач.WaitAll () waits tills все задачи выполнены. Аналогично, как узнать, когда все задания отменены как только общий источник токена отмены установлен на отмену.

4 ответов


Да, что вы сказали об использовании CancellationToken является правильным. Вы можете создать один CancellationTokenSource и использовать его CancellationToken для всех задач. Ваши задачи должны регулярно проверять токен на предмет отмены.

например:

const int NUM_TASKS = 4;

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;

Task[] tasks = new Task[NUM_TASKS];
for (int i = 0; i < NUM_TASKS; i++)
{
    tasks[i] = Task.Factory.StartNew(() =>
    {
        while (true)
        {
            Thread.Sleep(1000);
            if (ct.IsCancellationRequested)
                break;
        }
    }, ct);
}

Task.WaitAll(tasks);

ваша кнопка может вызвать cts.Cancel(); отменить задачи.

обновление для обновления вопроса:

есть несколько способов сделать то, что вы просите. Один из способов-использовать ct.IsCancellationRequested чтобы проверить отмену без бросая, затем позвольте вашей задаче завершить. Тогда Task.WaitAll(tasks) завершится, когда все задачи будут отменены.

я обновил код, чтобы отразить это изменение.


Да, вы должны передать тот же токен и использовать его, чтобы отменить все задачи за один раз, если это ваше намерение.


const int NUM_TASKS = 4;

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;

Task[] tasks = new Task[NUM_TASKS];
for (int i = 0; i < NUM_TASKS; i++)
{
    tasks[i] = Task.Factory.StartNew(() =>
    {
        while (true)
        {
            Thread.Sleep(1000);
            if (ct.IsCancellationRequested)
                break;
        }
    }, ct);
}

Task.WaitAll(tasks);

использовать BackroundWorker класса, расположен WorkerSupportsCancellation, начните задачи, позвонив RunWorkerAsync() и остановить их с помощью CancelAsync()

вы не neet для синхронизации кода с пользовательским интерфейсом.