我已经对Eric Lippert's answer评论了What's the difference between Task.Start/Wait and Async/Await?
我问这个问题,因为我仍然不确定我是否正确理解了这个概念以及我如何实现我的目标。添加大量评论对任何人都没有多大帮助。
我理解:await告诉编译器当前线程有能力执行其他一些计算,并在等待操作完成后返回。这意味着工作流程将中断,直到等待的操作完成。这不会加快包含await的上下文的计算速度,但会因为更好地使用worker而提高整体应用程序性能。
不,我的问题:我想继续工作流程,最后确保操作完成。所以基本上允许工作人员继续当前的工作流程,即使等待的操作没有完成并等待工作流程结束时完成。我希望工人花时间在我的工作流程上而不是逃跑并帮助别人。
我认为可能有用:考虑n async Add
操作和处理添加项目的Flush
操作。 Flush
要求添加项目。但添加项目不需要添加上一项。所以基本上我想收集所有正在运行的Add
操作并等待所有这些操作一旦添加完毕。在他们等待之后,他们应该是Flush
ed。
Add
任务添加到列表中来完成此操作,并最终等待所有这些任务吗?Add
操作相同? (没有收集它们)我理解:await告诉编译器当前线程有能力执行其他一些计算,并在等待操作完成后返回。
那非常接近。表征它的更好方法是:await意味着暂停此工作流,直到等待的任务完成。如果由于未完成任务而暂停工作流,则会释放此线程以查找更多工作,并且工作流将安排在任务完成时的某个时间点恢复。等待时做的选择是最近调用此工作流的代码;也就是说,await
实际上是一个奇特的return
。毕竟,return
意味着“让我的来电者决定下一步做什么”。
如果任务在等待点完成,则工作流程将正常继续。
Await是异步等待。它等待完成任务,但在等待时它一直忙着。
我想继续工作流程,最后确保操作完成。所以基本上允许工作人员继续当前的工作流程,即使等待的操作没有完成并等待工作流程结束时完成。我希望工人花时间在我的工作流程上而不是逃跑并帮助别人。
当然,那没关系。在工作流程可以继续之前需要完成任务时,不要等待任务直到最后一刻。这是最好的做法。
但是:如果你的工作流程正在进行超过30毫秒而不等待某事的操作,并且你在UI线程上,那么你可能会冻结UI并激怒用户。
我可以通过将添加任务添加到列表中来完成此操作,并最终等待所有这些任务吗?
当然可以;这是个好主意。使用WhenAll
组合器轻松等待所有一系列任务。
是否与直接等待所有Add操作相同? (没有收集它们)
不,这是不同的。正如您所正确注意的那样,等待每个Add操作将确保在上一个完成之前不会启动Add。如果不要求以这种方式序列化它们,您可以先通过启动任务,然后在它们全部启动后等待它们,从而提高工作效率。
如果我正确理解你的问题,你想要做的是并行化异步工作,这是非常常见的。
请考虑以下代码:
async Task Add(Item item) { ... }
async Task YourMethod()
{
var tasks = new List<Task>();
foreach (var item in collection)
{
tasks.Add(Add(item));
}
// do any work you need
Console.WriteLine("Working...");
// then ensure the tasks are done
await Task.WhenAll(tasks);
// and flush them out
await Flush();
}