非同期タスクについて学ぶために、こちらのサンプル コードに従っています。タスクの作業とメインの作業の出力を書くようにコードを修正しました。出力は次のようになります。
Wait() 呼び出しを削除すると、タスクがキャンセルされたときにスローされる例外をキャッチできないことを除いて、プログラムは同じように実行されることに気付きました。catch ブロックをヒットするために Wait() を必要とする舞台裏で何が起こっているのか誰か説明できますか?
1 つの警告として、Visual Studio デバッガーは、Console.WriteLine(" - task work");
"OperationCanceledException was unhandled by user code" というメッセージが表示された行で誤って停止します。その場合は、[続行] をクリックするか、F5 キーを押して、残りのプログラムの実行を確認してください。詳細については、 http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspxを参照してください。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
class Program
{
static void Main()
{
var tokenSource = new CancellationTokenSource();
var cancellationToken = tokenSource.Token;
// Delegate representing work that the task will do.
var workDelegate
= (Action)
(
() =>
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
// "If task has been cancelled, throw exception to return"
// Simulate task work
Console.WriteLine(" - task work"); //Visual Studio
//erroneously stops on exception here. Just continue (F5).
//See http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx
Thread.Sleep(100);
}
}
);
try
{
// Start the task
var task = Task.Factory.StartNew(workDelegate, cancellationToken);
// Simulate main work
for (var i = 0; i < 5; i++)
{
Console.WriteLine("main work");
Thread.Sleep(200);
}
// Cancel the task
tokenSource.Cancel();
// Why is this Wait() necessary to catch the exception?
// If I reomve it, the catch (below) is never hit,
//but the program runs as before.
task.Wait();
}
catch (AggregateException e)
{
Console.WriteLine(e.Message);
foreach (var innerException in e.InnerExceptions)
Console.WriteLine(innerException.Message);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}