質問

特定 System.Threading.Tasks.Task コンストラクターはaを取る CancellationToken パラメーターとして:

CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);

これについて私を困惑させているのは、からの方法がないということです 中身 実際に渡されたトークンに到達する方法本体 Task.CurrentTask.CancellationToken)。トークンは、状態オブジェクトなど、ラムダでキャプチャされた他のメカニズムを通じて提供する必要があります。

それでは、コンストラクターのキャンセルトークンを提供する目的は何ですか?

役に立ちましたか?

解決

このトークンをタスクコンストラクターに渡すと、このタスクに関連付けられます。

引用 MSDNからのStephen Toubの答え:

これには2つの主な利点があります。

  1. タスクが実行を開始する前にキャンセルが要求された場合、タスクは実行されません。に移行するのではなく Running, 、すぐに移行します Canceled. 。これにより、とにかく実行中にキャンセルされる場合、タスクを実行するコストが回避されます。
  2. タスクの本体がキャンセルトークンを監視している場合、 OperationCanceledException そのトークンを含む(これが何なのか ThrowIfCancellationRequested )、タスクがそれを見るとき OperationCanceledException, 、それはをチェックします OperationCanceledExceptionのトークンは、タスクのトークンと一致します。もしそうなら、その例外は、協同組合のキャンセルの認識と、タスクがキャンセルされた状態に移行する(障害状態ではなく)と見なされます。

他のヒント

コンストラクターは、内部的にキャンセル処理にトークンを使用します。コードがトークンにアクセスしたい場合は、自分に渡す責任があります。読むことを強くお勧めします CodePlexでMicrosoft .NETブックを使用した並列プログラミング.

本からのCTSの使用例:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task myTask = Task.Factory.StartNew(() =>
{
    for (...)
    {
        token.ThrowIfCancellationRequested();

        // Body of for loop.
    }
}, token);

// ... elsewhere ...
cts.Cancel();

キャンセルは、多くの人が考えるかもしれない単純なケースではありません。 MSDNに関するこのブログ投稿で説明されています。

例えば:

並列拡張および他のシステムの特定の状況では、ユーザーによる明示的なキャンセルによるものではない理由でブロックされた方法を覚ます必要があります。たとえば、コレクションが空になっているために1つのスレッドがBlockingCollection.take()でブロックされ、別のスレッドがBlockingCollection.comPleteAdding()を呼び出している場合、最初の呼び出しは目を覚まし、InvalidOperationExceptionをスローして誤った使用を表す必要があります。

http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top