3

非同期タスクについて学ぶために、こちらのサンプル コードに従っています。タスクの作業とメインの作業の出力を書くようにコードを修正しました。出力は次のようになります。

ここに画像の説明を入力

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();
   }
}
4

3 に答える 3