Почему я должен использовать CancellationToken.ThrowIfCancellationRequested? - PullRequest
0 голосов
/ 14 мая 2018

У меня есть следующий пример приложения:

using System;
using System.Threading;
using static System.Threading.Thread;
using static System.Console;

internal static class ThreadCancellation
{
    private static void Main()
    {
        var cancellationTokenSource = new CancellationTokenSource();
        var cancellationToken = cancellationTokenSource.Token;
        ThreadPool.QueueUserWorkItem(x => Counter(cancellationToken));
        ThreadPool.QueueUserWorkItem(x => CounterWithThrow(cancellationToken));
        Sleep(10);
        cancellationTokenSource.Cancel();
        Sleep(10);
    }

    private static void Counter(CancellationToken cancellationToken)
    {
        WriteLine($"Counter running on {CurrentThread.ManagedThreadId}.");
        while (!cancellationToken.IsCancellationRequested)
        {
            WriteLine($"Thread {CurrentThread.ManagedThreadId}:  {DateTime.Now.Ticks}");
            Sleep(1);
        }

        WriteLine("Counter() was canceled");
    }

    private static void CounterWithThrow(CancellationToken cancellationToken)
    {
        WriteLine($"CounterWithThrow running on {CurrentThread.ManagedThreadId}.");

        try
        {
            while (true)
            {
                WriteLine($"Thread {CurrentThread.ManagedThreadId}:  {DateTime.Now.Ticks}");
                cancellationToken.ThrowIfCancellationRequested();
                Sleep(1);
            }

        }
        catch (OperationCanceledException e)
        {
            WriteLine($"Thread {CurrentThread.ManagedThreadId}: Caught OperationCanceledException: {e.Message}");
        }
    }
}

, который работает так, как я ожидал, и выводит:

Counter running on 4.
CounterWithThrow running on 3.
Thread 4:  636619039468459034
Thread 3:  636619039468459034
Thread 4:  636619039468530368
Thread 3:  636619039468530368
Thread 4:  636619039468550400
Counter() was canceled
Thread 3:  636619039468550400
Thread 3: Caught OperationCanceledException: The operation was canceled.

Почему я бы выбрал OperationCancelledExceptionoption?

  1. Должно ли это быть исключением?
  2. Убирать в catch гораздо сложнее, чем делать это изящно.
  3. Если бы я захотелдля этого было бы тривиально реализовать оператор if.

Учитывая, что это, вероятно, есть веская причина, что это за причина?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...