次のサンプルコードがあります。
static class Program
{
static void Main()
{
var cts = new CancellationTokenSource();
var task = Task.Factory.StartNew(
() =>
{
try
{
Console.WriteLine("Task: Running");
Thread.Sleep(5000);
Console.WriteLine("Task: ThrowIfCancellationRequested");
cts.Token.ThrowIfCancellationRequested();
Thread.Sleep(2000);
Console.WriteLine("Task: Completed");
}
catch (Exception exception)
{
Console.WriteLine("Task: " + exception.GetType().Name);
throw;
}
}).ContinueWith(t => Console.WriteLine("ContinueWith: cts.IsCancellationRequested = {0}, task.IsCanceled = {1}, task.Exception = {2}", cts.IsCancellationRequested, t.IsCanceled, t.Exception == null ? "null" : t.Exception.GetType().Name));
Thread.Sleep(1000);
Console.WriteLine("Main: Cancel");
cts.Cancel();
try
{
Console.WriteLine("Main: Wait");
task.Wait();
}
catch (Exception exception)
{
Console.WriteLine("Main: Catch " + exception.GetType().Name);
}
Console.WriteLine("Main: task.IsCanceled = {0}", task.IsCanceled);
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
出力は次のとおりです。
- タスク: 実行中
- メイン:キャンセル
- メイン:待って
- タスク: ThrowIfCancellationRequested
- タスク: OperationCanceledException
- ContinueWith: cts.IsCancellationRequested = True、task.IsCanceled = False、task.Exception = AggregateException
- メイン: task.IsCanceled = False
- 終了するには、任意のキーを押してください...
ContinueWith を削除すると、出力は次のようになります。
- タスク: 実行中
- メイン:キャンセル
- メイン:待って
- タスク: ThrowIfCancellationRequested
- タスク: OperationCanceledException
- メイン: AggregateException をキャッチする
- メイン: task.IsCanceled = False
- 終了するには、任意のキーを押してください...
なぜ task.IsCanceled が両方のケースで false を返すのかわかりません。
そして、ContinueWith なしでのみ例外が再スローされるのはなぜですか?
私が達成しようとしているのは、タスクの完了を待つための統一された簡単な方法と、タスクがキャンセルされたかどうかを示すプロパティです。