繁体   English   中英

C#“等待”实际上返回什么?

[英]What does C# “await” actually return?

下面是一些在LinqPad中“按原样”运行的代码。 它表明了我对正在await的事情的误解。 进一步了解结果和我的问题。

    void Main()
{
    var cts = new CancellationTokenSource();
    StartIt(cts.Token);
    Thread.Sleep(500);
    "Cancelling".Dump();
    cts.Cancel();
}


// Define other methods and classes here
async Task StartIt(CancellationToken token)
{
    "StartIt".Dump();
    var o = new TestClass();

    await o.Step0(token);

}

public class TestClass
{
    public async Task Step0(CancellationToken token)
    {
        var t = Step1(token);
        ("Step0.Task.Id => " + t.Id).Dump();        

        await t;
        ("Step0.IsCancelled? " + t.IsCanceled).Dump();
    }

    public async Task Step1(CancellationToken token)
    {
        var t = Step2(token);
        ("Step1.Task.Id => " + t.Id).Dump();

        try {
            await t;
        }
        catch (OperationCanceledException)
        {
            "Step1.OperationCanceledException".Dump();
        }
        ("Step1.IsCancelled? " + t.IsCanceled).Dump();
    }

    public Task Step2(CancellationToken token)
    {
        return Task.Run(() =>{
                Thread.Sleep(3000);
                token.ThrowIfCancellationRequested();
                "Done".Dump();
            }, token);
    }
}

因此上面产生:

StartIt
Step1.Task.Id => 17
Step0.Task.Id => 18
Cancelling
Step1.OperationCanceledException
Step1.IsCancelled? True
Step0.IsCancelled? False

我的问题:

我希望Step0和Step1的task.Id相同。 (因此)我希望取消会传播到方法上,以便我可以询问t.IsCanceled并采取适当的措施。

但是我得到了一个不同的Task返回到Step0 我想念什么?

谢谢

我建议您阅读async 另外,LinqPad内置了一个出色的教程(《 C#5交互式教程》中的[示例->下载/导入更多示例->异步)。

async代码中的任务标识符可能有些棘手。 发生的情况是,每个async Task方法都会创建自己的任务,以表示该方法的调用。 因此, Task.Run创建一个Task并将其返回到Step2Step1 (测试中的ID 17 )。 Step1还会创建一个Task ,并将其返回到Step0 (测试中的ID 18 )。 Step0还创建一个Task并将其返回给StartIt ,而StartIt也创建一个Task并将其返回给Main

所以, Task返回的Task.Run (这是相同的Task由返回Step2 )被取消。 Step1捕获已取消的异常,因此它会正常返回,并且不会取消Step1返回的Task

如果要传播异常,请不要捕获已取消的异常(或者,如果您确实想捕获已记录的异常,请通过throw;将其重新throw; )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM