2

キャンセルトークンを使用してタスクをキャンセルする方法を学ぼうとしています。ここでは、UnitTest を作成しましたが、動作がわかりません。

[TestMethod]
public async Task Task_should_not_run_when_token_cancelled_before_its_call()
{
    var cts = new CancellationTokenSource();
    var token = cts.Token;

    cts.Cancel();

    Debug.WriteLine("Calling Cancellable Method".ToUpper());
    try
    {
        await CheckMeCalled(token);
    }
    catch (Exception expException)
    {

    }
}

private async Task CheckMeCalled(CancellationToken ct)
{
    Debug.WriteLine("Before task delayed".ToUpper());
    await Task.Delay(5000);
    Debug.WriteLine("After task delayed".ToUpper());
}

上記のテストではcts.Cancel()、メソッドを呼び出す前に を呼び出しましたCheckMeCalled。そのため、キャンセルされたときに実行されるべきではありません。しかし、それは完全に実行されています。

私はどこかでそれを読んだ:

タスクが実行されていないときにキャンセルすると、実行中の状態にはならず、呼び出したときにキャンセルされた状態になります。

しかし、ここで起こっているようには見えません。誰か説明してくれませんか?

4

2 に答える 2

6

あなたが追加した引用は、新しいTaskビアTask.Runまたはの作成に関連していましたTask.Factory.Startnew。メソッドにa を渡すときはCancellationToken、実行する前にトークンを積極的にチェックする必要があります

private async Task CheckMeCalled(CancellationToken ct)
{
    ct.ThrowIfCancellationRequested();
    Debug.WriteLine("Before task delayed".ToUpper());
    await Task.Delay(5000, ct);
    Debug.WriteLine("After task delayed".ToUpper());
}

以下は、キャンセル トークンと に関する Stephan Toub の引用Taskです。

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

また、PFX チームによるキャンセル メカニズムの広範なレビューについては、NET 4 Cancellation Frameworkを読むことをお勧めします。

于 2014-07-11T14:04:18.620 に答える
1

トークンを手動でチェックして、キャンセルが要求されたかどうかを確認する必要があります。

と:

ct.IsCancellationRequested
于 2014-07-11T14:01:45.073 に答える