25

長時間実行されるプロセスをシミュレートする新しいタスクを作成するサンプル コードを次に示します。そのようなタスクには何もなく、純粋にキャンセル機能に焦点を当てています. キャンセルトークンを使用してタスクをキャンセルしていますが、コードは正常に機能します。

CancellationTokenSource CTS = new CancellationTokenSource();

Task<Boolean> PTask = new Task<Boolean>(() => 
{
   while (true)
   {
       if (!CTS.Token.IsCancellationRequested)
       {
          Thread.Sleep(5000);
       }
       else { Console.WriteLine("Thread Cancelled");break; }
   }
   return true;

}, CTS.Token, TaskCreationOptions.None);

PTask.Start();
Console.WriteLine("Hit Enter to cancel the Secondary thread you have started");
Console.ReadLine();
CTS.Cancel();
System.Console.WriteLine(PTask.Result);

しかし、私が理解できなかったのは、コンストラクターCTS.Tokenに渡されるトークン パラメーター ( ) です。Taskトークンをコンストラクターに渡さなくても実際にタスクをキャンセルできる場合、パラメーターを渡すことの実際の使用法は何ですか。

以下は、トークン パラメーターなしで動作するわずかに変更されたバージョンです。

CancellationTokenSource CTS = new CancellationTokenSource();
Task<Boolean> PTask = new Task<Boolean>(() => 
{
   while (true)
   {
       if (!CTS.Token.IsCancellationRequested)
       {
           Thread.Sleep(5000);
       }
       else
       {
           Console.WriteLine("Thread Cancelled");
           break;
       }
};
4

1 に答える 1

41

更新: 次のmsdnの質問で理由が説明されています。

トークンを StartNew に渡すと、トークンがタスクに関連付けられます。これには主に 2 つの利点があります。

  1. タスクが実行を開始する前にトークンにキャンセルが要求された場合、タスクは実行されません。Running に移行するのではなく、すぐに Canceled に移行します。これにより、実行中にタスクがキャンセルされた場合に、タスクを実行するコストが回避されます。

  2. タスクの本体もキャンセル トークンを監視しており、そのトークンを含む OperationCanceledException をスローする ThrowIfCancellationRequested場合 (実際にそうです)、タスクがその OCE を確認すると、OCE のトークンがタスクのトークンと一致するかどうかを確認します。一致する場合、その例外は協調キャンセルの確認と見なされ、タスクは (Faulted 状態ではなく) Canceled 状態に遷移します。

于 2012-06-01T10:30:03.530 に答える