Токен отмены в конструкторе задач: почему?



некоторых System.Threading.Tasks.Task конструкторы возьми CancellationToken параметр:



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


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



Итак, какой цели служит предоставление токена отмены в конструкторе?

620   3  

3 ответов:

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

цитирую ответ Стивена туба от MSDN:

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

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

конструктор использует маркер для внутренней обработки отмены. Если ваш код хочет получить доступ к токену, вы несете ответственность за его передачу себе. Я бы очень рекомендовал прочитать параллельное программирование с Microsoft .NET книга в CodePlex.

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

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:

например:

в некоторых ситуациях в параллельных расширениях и в других системах это необходимо разбудить заблокированный метод по причинам, которые не связаны до явной отмены пользователем. Например, если один поток заблокирован на blockingCollection.Take () из-за того, что коллекция пуста и еще одна нить впоследствии звонки blockingCollection.CompleteAdding (), то первый вызов должен проснуться вверх и бросьте исключение InvalidOperationException для представления неправильного использование.

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

Comments

    Ничего не найдено.