C# 取消令牌的使用

C# 取消令牌的使用,c#,.net,windows-phone-8,async-await,cancellation-token,C#,.net,Windows Phone 8,Async Await,Cancellation Token,我正在尝试学习如何使用取消令牌取消任务。 在这里,我已经为它编写了一个单元测试,但我不了解它的工作方式 [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.Writ

我正在尝试学习如何使用取消令牌取消任务。 在这里,我已经为它编写了一个单元测试,但我不了解它的工作方式

[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());
}
在上面的测试中,在调用
CheckMeCalled
方法之前,我调用了
cts.Cancel()
。因此,它不应该在取消时运行。但它正在全力运行

我在某处读到:

若任务未运行,而您取消了它,那个么当您调用它时,它将不会进入运行状态,而是进入取消状态


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

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

与:


您添加的报价与通过
Task.Run
Task.Factory.Startnew创建新的
Task
相关。将
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关于取消令牌和任务的引用:

如果令牌在任务开始执行之前已请求取消,则该任务将不会执行。它不会转换为运行,而是会立即转换为取消。这避免了运行任务的成本,如果任务在运行时被取消

我还建议阅读PFX团队对取消机制的广泛审查

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());
}