Немедленная отмена задачи - PullRequest
0 голосов
/ 30 августа 2018

У меня есть вопрос относительно отмены задачи с использованием cancellationToken и cancellationTokenSource:

Обычный способ выглядит следующим образом:

var cts = new CancellationTokenSource();
var t = Task.Run(() => {    
while(true)
  {
    if (!cts.IsCancellationRequested)   
     {  //do stuff }
  }
}, cts.Token);

Итак, цикл while продолжается до тех пор, пока не будет запрошен токен. Сегодня, изучая метод Cancel(), я обнаружил, что вы можете использовать метод Register() для определения другого кода, запускаемого при запросе токена, поэтому мне было интересно, что если кто-то напишет что-то вроде этого:

var cts = new CancellationTokenSouce();
token=cts.Token;
token.Register(
() => {
//do something to manage the cancel call
return;
};
) 
var t = Task.Run(() => {
//do stuff 
}, cts.Token);

При этом задача, связанная с CancellationToken, сразу же перестает выполняться, вместо того, чтобы завершать текущий для итерации, как в обычной реализации. Мой вопрос: это правильный способ немедленно остановить Task или есть лучший способ?

1 Ответ

0 голосов
/ 30 августа 2018

Register не приводит к прекращению выполнения задачи, это просто уведомление о том, что запрос отменен. Основная цель Register - иметь возможность отменять асинхронные операции, которые не поддерживают CancellationToken, но имеют собственный механизм отмены или могут быть отменены косвенно (например, путем закрытия сокета). Есть также некоторые приемы, описанные Стивеном Тубом здесь , как отменить неотменяемые задачи с помощью Register. Однако если вы контролируете выполнение задачи, которая должна быть отменена, вы обязаны предоставить механизм для отмены выполнения. Не существует лучшего подхода, как отменить любую задачу - некоторые задачи могут быть отменены немедленно (вы можете использовать ThrowIfCancellationRequested), некоторые могут потребовать некоторой дополнительной обработки (вам нужно проверить, что запрос отменен, сделать что-то, а затем выдать исключение ).

...