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。所以它不应该在取消时运行。但它正在全力以赴。

我在某处读过:

如果 Task 没有运行并且你取消它,那么它不会进入运行状态,而是在你调用它时进入取消状态。

但这似乎并没有在这里发生。有人能给我解释一下吗?

4

2 回答 2

6

您添加的报价与创建新的TaskviaTask.RunTask.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。这避免了运行任务的成本,如果它只是在运行时被取消的话。

我还建议阅读NET 4 Cancellation Framework,以全面了解 PFX 团队的取消机制

于 2014-07-11T14:04:18.620 回答
1

您必须手动检查令牌以查看是否请求取消。

和:

ct.IsCancellationRequested
于 2014-07-11T14:01:45.073 回答