Почему существует второй параметр типа CancelationToken для метода Task.Run ()? - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь понять необходимость перегруженного метода Task.Run (Func, CancellationToken) .

Почему существует второй параметр типа CancelationToken, если он даже не передан в функцию, указанную в первом параметре метода Task.Run()? Там я вынужден использовать замыкание для этого в коде функции sum. Кроме того, я вижу то же самое в примере кода Microsoft (см. Ссылку выше).

Это мой код:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadsLearning {
    class Program {

        private static void Main(string[] args) {

            CancellationTokenSource tokenSrc = new CancellationTokenSource();

            Func<int, int> sum = n => {
                int result = 0;

                for (var i = 0; i <= n; i++) {
                    result += i;

                    tokenSrc.Token.ThrowIfCancellationRequested();

                    Console.WriteLine(result);
                    Thread.Sleep(200);
                }
                return result;
            };

            /* Why does exist a second parameter of CancelationToken type, if it
             * is even not passed into the function specified in the first parameter
             * of Task.Run() method?
             * I'm forced to use a closure for this in the 'sum' function code.
             */
            var task = Task.Run(() => sum(30), tokenSrc.Token);

            // I will get the seame result for CancellationToken.None:
            // var task = Task.Run(() => sum(30), CancellationToken.None);

            tokenSrc.CancelAfter(TimeSpan.FromSeconds(2));

            try {
                Console.WriteLine("Result: {0}", task.Result);
            }
            catch (AggregateException ex) {
                foreach (var item in ex.InnerExceptions) {
                    Console.WriteLine("Exception: {0}", item.Message);
                }
            }
            catch (Exception ex) {
                Console.WriteLine("Other exception (the other 'catch' block): {0}", ex.Message);
            }

            Console.WriteLine("Hit <Enter> for exit...");
            Console.ReadLine();
        }
    }
}

1 Ответ

0 голосов
/ 30 апреля 2018

У этого есть две причины:

  • Если отмена уже запрашивается при вызове Task.Run, передача CancellationToken гарантирует, что ваш код никогда не запускается.
  • Если ваш код выдает OperationCanceledException из того же CancellationToken, который был передан, задание будет помечено как отмененное, а не как неудачное. Другой код может проверять состояние задачи и соответственно изменять поведение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...