Какая польза от передачи CancellationToken в конструктор класса задач?

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

       CancellationTokenSource CTS= new CancellationTokenSource();

       Task<Boolean> PTask = new Task<Boolean>(() => 
       {
           while (true)
           {
               if (!CTS.Token.IsCancellationRequested)
               {
                  Thread.Sleep(5000);
               }
               else{Console.WriteLine("Thread Cancelled");break;}
           }
           return true;

       }, CTS.Token, TaskCreationOptions.None);

       PTask.Start();
       Console.WriteLine("Hit Enter to cancel the Secondary thread you have started");
       Console.ReadLine();
       CTS.Cancel();
       System.Console.WriteLine(PTask.Result);

    }
}

Но то, что я не мог понять, - это параметр токена (CTS.Token), который передается конструктору задач. Каково фактическое использование передачи параметра, когда я действительно могу отменить задачу, даже не передав токен в конструктор

Ниже приведена слегка измененная версия, которая работает без параметра токена.

      CancellationTokenSource CTS= new CancellationTokenSource();
      Task<Boolean> PTask = new Task<Boolean>(() => 
       {
           while (true)
           {
               if (!CTS.Token.IsCancellationRequested)
               {
                   Thread.Sleep(5000);
               }
               else
               {
                   Console.WriteLine("Thread Cancelled");
                   break;
               }
       };
 Slugart01 июн. 2012 г., 15:01
Я бы порекомендовал прочитать: Blogs.msdn.com / б / pfxteam / архив / 2009/05/22 / 9635790.aspx

Ответы на вопрос(1)

Решение Вопроса

@ MS вопрос описывает причину:

Передача токена в StartNew связывает токен с задачей. Это имеет два основных преимущества:

Если токен запросил отмену до начала выполнения Задачи, Задача не будет выполнена. Вместо перехода в режим «Бег», он немедленно перейдет в режим «Отменено». Это позволяет избежать затрат на выполнение задачи, если она все равно будет отменена во время выполнения.

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

 daryal01 июн. 2012 г., 15:04
Я не вижу никакой другой причины передачи токена конструктору, но если вы спрашиваете, уверен ли я на 100%; ну нет.
 psaxton18 окт. 2016 г., 18:34
Point 2 кажется недействительным.Task.Run(async () => { throw new OperationCanceledException(); }, new CancellationToken(false)).ContinueWith(tsk => Console.WriteLine(tsk.Status)) возвращает Отменено, а не Ошибка.
 Prabhu Murthy01 июн. 2012 г., 14:58
Вы говорите, что проверка iscancelrequest с токеном основного потока небезопасна.
 daryal01 июн. 2012 г., 15:09
Я обновил, на самом деле это никак не связано с безопасностью потоков.

Ваш ответ на вопрос