异步方法await关键字不会挂起到调用方法

时间:2017-06-05 20:04:27

标签: c# .net async-await task-parallel-library c#-5.0

我有以下代码行,以了解async-await并暂停直到等待任务完成。

public async Task<string> WaitAsynchronouslyAsync()
    {
        var results = await WaitAsync();
        Console.WriteLine($@"I am not waiting");
        return results;
    }

    public async Task<string> WaitAsync()
    {
        await Task.Delay(10000).ConfigureAwait(false);
        return "Async programming suspension point demo.";
    }

await运算符暂停执行,直到WaitAsync()(延迟10秒)方法的工作完成。

与此同时,我期待Console.WriteLine($@"I am not waiting");应该将文本写入输出窗口,直到等待任务完成,因为控件将返回给WaitAsync()的调用者。当任务完成执行时,await表达式将计算字符串("Async programming suspension point demo.")。

  

我在这里与悬浮指针与调试指针混淆了吗?

3 个答案:

答案 0 :(得分:7)

  

await运算符暂停执行,直到WaitAsync()方法的工作完成。

正确。

  

我期待着Console.WriteLine($ @“我不等待”);应该将文本写入输出窗口,直到等待任务完成,因为控制权返回给WaitAsync()的调用者。

为什么呢?您刚才说 await运算符暂停执行直到工作完成。这项工作将在另外10秒内完成;工作是等待十秒。在WaitAsync执行return之前,WaitAsynchronouslyAsync工作尚未完成。

正确的做法是await允许调用者在此方案中运行。

您已正确说明await的含义,但您似乎并未完全内化后果。 text-overflow:ellipsis检查其操作数以查看任务是否完成。如果是,则获取任务的结果并继续该方法。如果不是,那么该方法的其余部分将作为该任务的继续进行注册,并且产生控制以便可以在其他地方完成更多工作。将来,当任务完成时,该方法的其余部分将被安排执行。

答案 1 :(得分:4)

await表示“等到异步执行完毕”,在提供的Task完成执行之前,您的函数将不会继续。

如果您改为说以下内容,则不会等待:

var results = WaitAsync();
Console.WriteLine($@"I am not waiting");
return await results;

或者更简洁,从签名中删除async,然后您就可以return results;

答案 2 :(得分:3)

操作顺序将如下所示:

  1. 您致电WaitAsynchronouslyAsync
  2. WaitAsynchronouslyAsync来电WaitAsync
  3. WaitAsync调用Task.Delay(10000).ConfigureAwait(false),生成Task
  4. WaitAsync向其来电者Task返回新的WaitAsynchronouslyAsync,该广告将在稍后完成
  5. WaitAsynchronouslyAsync等待来自WaitAsync的任务,然后返回它的来电,提供表示何时完成的Task
  6. 其他内容在调用堆栈中进一步发生。
  7. Task.Delay结束,所以WaitAsync的继续发生火灾,从它停止的地方开始。
  8. WaitAsync返回字符串,填写Task
  9. WaitAsynchronouslyAsync现在可以继续,因为从Task返回的WaitAsync已经完成。它将继续将文本打印到控制台。
  10. WaitAsynchronouslyAsync完成它的任务,让任何有任何设置的人在完成后运行。