11

次のタスクを定義しました

var t = Task.Factory.StartNew(
    () => LongRunningMethod( cancellationToken ),
    cancellationToken
);

t.ContinueWith(
    Callback,
    cancellationToken,
    TaskContinuationOptions.None,
    TaskScheduler.FromCurrentSynchronizationContext()
);

の中でLongRunningMethod、キャンセルトークンにキャンセルが要求されているかどうかを確認し、要求されている場合はメソッドから戻ります。それだけでうまくいきます。

ただし、このシナリオではコールバックは呼び出されません。上記の2行目を次のように置き換えると、コールバックが呼び出されます

t.ContinueWith(
    x => Callback( x, cancellationToken ),
    TaskScheduler.FromCurrentSynchronizationContext()
);

この状況でも、タスクは実行が完了したと見なします。

最初の呼び出しが機能しないのはなぜですか?TaskContinuationOptions.Noneスレッドの状態に関係なく、コールバックが呼び出されるという印象を受けました。

次の電話でタスクをキャンセルします。

_cancellationTokenSource.Cancel();

やや関連性のある注意点として、キャンセルトークンを渡さなければならないことは、タスクライブラリの主要な設計上の欠陥のように思われます。

4

1 に答える 1

21

継続タスクは、キャンセルしたCancellationTokenを受け取ります。これは、継続タスクが開始されていない間、キャンセルされていることを意味します。キャンセルしたくないものにそのトークンを渡さないでください。

CancellationTokenは、アクションのグラフ全体を一度にキャンセルすることを目的としています。トークンを渡さないことで、キャンセルから除外することができます。

于 2012-08-09T21:38:48.730 に答える