@oleg_ods

Зачем нужен метод CreateLinkedTokenSource(CancellationToken)?

Зачем нужен метод CreateLinkedTokenSource(CancellationToken)? Вопрос именно по поводу перегрузки метода с одним параметром CancellationToken. Я понимаю, что это возможность создать цепочку методов которая должна прерваться полностью при запросе отмены у одного токена. Но почему тогда не передать один токен во все методы цепочки?

Вот например,
static void Main(string[] args)
        {
            var ctx = new CancellationTokenSource();

            var task = FirstMethodAsync(ctx.Token);
            //var task = FirstMethodLinkedAsync(ctx.Token); // Результат идентичен вызову метода FirstMethodAsync.

            ConsoleKeyInfo key;

            while (!task.IsCompleted)
            {                
                key = Console.ReadKey();

                if (key.KeyChar == 'e')
                {
                    ctx.Cancel();                    
                }
            }

            Console.WriteLine("Good buy!");
        }

        static async Task FirstMethodAsync(CancellationToken cancellationToken)
        {
            var secondTask = SecondMethodAsync(cancellationToken);
            while (true)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    Console.WriteLine("First method cancelled");
                    return;
                }
                Console.WriteLine("First method: {0}", DateTime.Now.ToLongTimeString());
                await Task.Delay(500);
            }
        }

        static async Task FirstMethodLinkedAsync(CancellationToken cancellationToken)
        {
            var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            var secondTask = SecondMethodAsync(cts.Token);
            while (true)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    Console.WriteLine("First method cancelled");
                    return;
                }
                Console.WriteLine("First method: {0}", DateTime.Now.ToLongTimeString());
                await Task.Delay(500);
            }
        }

        static async Task SecondMethodAsync(CancellationToken cancellationToken)
        {
            while (true)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    Console.WriteLine("Second method cancelled");
                    return;
                }
                Console.WriteLine("Second method: {0}", DateTime.Now.ToLongTimeString());
                await Task.Delay(750);
            }
        }


Результаты обоих вызовов, на мой взгляд, идентичны. Зачем тогда создавать еще один CancellationTokenSource если можно просто передать готовый CancellationToken в следующий метод?
  • Вопрос задан
  • 72 просмотра
Решения вопроса 1
vabka
@vabka Куратор тега C#
Токсичный шарпист
Не уверен, когда именно это может понадобится в реальной жизни (у самого не было такой потребности), но например:
1. Тебе пришёл CancellationToken, но ты хочешь добавить новую причину, по которой может отметиться выполнение, в дополнение к той, по которой сработает первый CancellationToken
2. Ты создаёшь свой CTS и прилинковываешь его к первому токену.
Профит, задача решена - твой метод может отмениться как извне, так и по каким-то своим внутренним причинам.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы