У меня есть следующий пример приложения:
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.
Почему я бы выбрал OperationCancelledException
option?
- Должно ли это быть исключением?
- Убирать в
catch
гораздо сложнее, чем делать это изящно. - Если бы я захотелдля этого было бы тривиально реализовать оператор
if
.
Учитывая, что это, вероятно, есть веская причина, что это за причина?