Вопрос

Определенный System.Threading.Tasks.Task Конструкторы принимают CancellationToken как параметр:

CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);

Что меня сбивает с толку, так это то, что нет никакого способа от внутри тело метода, которое фактически попало в токен, пройденное (например, ничего похожего на Task.CurrentTask.CancellationToken) Токен должен быть предоставлен с помощью какого -либо другого механизма, такого как объект состояния или запечатлен в лямбде.

Так какую цель предоставит токен отмены в конструкторе?

Это было полезно?

Решение

Передача этого токена в конструктор задачи связывает его с этой задачей.

Цитата Ответ Стивена Тоуба от MSDN:

Это имеет два основных преимущества:

  1. Если токен имеет отмену, запрошенную до начала выполнения задачи, задача не выполняется. А не переходить на Running, это сразу же перейдет к Canceled. Анкет Это избегает затрат на выполнение задачи, если она будет просто отменена во время работы.
  2. Если тело задания также контролирует токен отмены и бросает OperationCanceledException содержащий этот токен (что и что ThrowIfCancellationRequested делает), тогда, когда задача видит, что OperationCanceledException, это проверяет, есть ли OperationCanceledExceptionТокен соответствует жетону задачи. Если это произойдет, это исключение рассматривается как подтверждение отмены кооперативной отмены, а задача переходит в отмененное состояние (а не в неисправное состояние).

Другие советы

Конструктор использует токен для обработки отмены внутренне. Если ваш код хотел бы получить доступ к токену, вы несете ответственность за передачу его себе. Я очень рекомендую прочитать Параллельное программирование с книгой Microsoft .net At Codeplex.

Пример использования CT из книги:

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

Task myTask = Task.Factory.StartNew(() =>
{
    for (...)
    {
        token.ThrowIfCancellationRequested();

        // Body of for loop.
    }
}, token);

// ... elsewhere ...
cts.Cancel();

Отмена не является простым случаем, как многие могут подумать. Некоторые из тонкостей объяснены в этом блоге на MSDN:

Например:

В определенных ситуациях в параллельных расширениях и в других системах необходимо разбудить заблокированный метод по причинам, которые не связаны с явной отменой пользователем. Например, если один поток блокируется на блокировке.

http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top