'await Task.Run(() => DoWork1Async())' 而不是 'await DoWork1Async()'?

  • 本文关键字:await DoWork1Async Task Run c#
  • 更新时间 :
  • 英文 :


有以下方法,

async Task DoWork1Async() { .... };
async Task DoWork2Async() { .... };
async Task DoWork3Async() { .... };

我阅读了以下代码

await Task.Run(() => DoWork1Async());
await Task.Run(() => DoWork2Async());
await Task.Run(() => DoWork3Async());

而不是

await DoWork1Async();
await DoWork2Async();
await DoWork3Async();

这两者有什么区别?

当您运行(在标记为async的方法内(时

await DoWork1Async();

您的代码在编译器设置的状态机中调用DoWork1Async。在这一点上,您的代码将控制权交还给那个状态机。任务完成后,方法中的其余代码将继续。

请记住,async代码不一定在单独的线程上运行(例如,如果您正在执行异步I/O(。

运行时:

await Task.Run(() => DoWork1Async());

将您的DoWork1Async作为工作分派到线程池。它在不同的线程(线程池线程(上执行。当这项工作完成后,相同的状态机机制将控制权交还给代码以继续运行。

在第二种情况下,代码总是在线程池线程上运行。在第一种情况下,您可能根本没有使用额外的线程(取决于DoWork1Async的编码方式(

await Task.Run(() => DoWork1Async());

启动一个Task,该Task将调用DoWork1Async。无论DoWork1Async是如何实现的,这都保证是异步的。

注意:CCD_ 7返回一个CCD_,而不是CCD_ 9。当lambda返回Task时,Task。Run((返回一个任务,该任务完成后会得到内部任务的结果。因此,您不需要做像await await Task.Run(() => return a Task)这样尴尬的事情。


await DoWork1Async();

在当前线程上同步调用DoWork1Async。如果DoWork1Async执行await语句,那么工作将被挂起,其余的工作将异步进行。但是,如果DoWork1Async在未命中await的情况下完成执行,则控制将返回给调用方,然后将全部同步启动DoWork2Async


简而言之,第一种形式保证DoWork1Async不会同步启动或完成。

第二个表单将同步启动DoWork1Async,甚至可能同步完成它,这取决于它的编写方式。

--这里有一把小提琴显示了差异:

https://dotnetfiddle.net/GhrO8x

请注意,在第一种情况下,DoWork()是如何在我们等待其Task之前完全同步启动和执行的,而在第二种情况中,它是在我们等待它的任务之后异步执行的。

最新更新