在单个异步方法中有多个等待的目的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在单个异步方法中有多个等待的目的相关的知识,希望对你有一定的参考价值。
如果您有异步功能:
public async Task DoWork()
{
await DoSomeWorkAsync();
await DoSomeMoreWorkAsync();
}
现在第一个await阻止了阻塞调用上下文的方法,因此很有用。
但是在DoSomeWorkAsync
完成之后,该方法无论如何都在不同的上下文中运行,因为在编译器中它被转换为类似Task.ContinueWith(await DoSomeMoreWorkAsync())
的东西。
他们等待DoSomeMoreWorkAsync
/运行异步的任何目的是什么?有什么缺点吗?如果它存在,我应该使用非同步版本的DoSomeMoreWorkAsync
吗?
即。这会不会有任何不利之处:
public async Task DoWork()
{
await DoSomeWorkAsync();
DoSomeMoreWork();
}
编辑:这与Multiple Awaits in a single method不是同一个问题。那询问会发生什么。我在问这件事有什么好处。
您似乎在考虑避免阻塞调用方是异步方法的唯一目的,但事实并非如此。异步方法通常是异步的,因为它们在某些时候执行异步IO,例如处理文件,数据库,Web请求等(或调用执行此操作的其他异步方法)。
当真正的异步IO正在进行中时,应用程序中的任何线程都没有忙着等待它完成(好吧,有线程,但它是整个应用程序的一个,而不是每个特定的IO任务)。
这意味着即使IF await DoSomeMoreWorkAsync
在某个线程池线程上执行 - 在某些时候它将达到异步IO - 此线程池线程将被释放并可用于更有用的工作。
另一方面,如果您将使用同步版本(DoSomeMoreWork
) - 它将在整个持续时间内阻止当前线程池线程,包括IO,因此该线程将无法用于有用的工作。
尽可能释放线程在使用它们的应用程序中非常重要,例如Web应用程序。
除上述内容外,此声明
但是在DoSomeWorkAsync完成之后,该方法无论如何都在不同的上下文中运行
并非总是如此。例如,在UI应用程序中,如果从UI线程调用DoWork
,则还将在UI线程上执行continuation(await DoSomeMoreWorkAsync()
)。这意味着如果用同步版本替换它 - UI线程将在其持续时间内冻结。
那么等待
DoSomeMoreWorkAsync
有什么目的吗?
好吧,如果它是异步的,那么你绝对想要等待它,所以你的DoWork
方法在完成“更多工作”之前没有完成。如果它是异步的,并且你没有等待它,它本质上是火,忘记哪个很少你想要的。
那么运行它是否有任何目的异步?
这取决于功能。您不要使方法异步,因为您要将它们称为异步。方法是异步的,因为它们执行异步任务。
如果该方法正在进行纯粹的CPU绑定工作,无论如何都不会异步运行,那么就没有理由让它异步,不。实际上,让它保持同步,以便与调用者清楚地通信,即没有异步进程正在进行。
但是,如果它是从异步中受益的东西,例如因为它执行异步网络或I / O调用,所以它可能应该是异步的。然后你也应该等待它。
有什么缺点吗?
总有缺点。运行异步代码比运行同步代码更昂贵,因为生成并调用了很多开销(我们在编写异步代码时很幸运不需要处理)。但是,在查看真正的异步代码可以为您提供的优势时,这种开销并不重要。
所以你真的不应该用它来决定是否要异步。考虑一下该方法的作用以及它是如何做的,然后决定该进程是同步还是异步。
以上是关于在单个异步方法中有多个等待的目的的主要内容,如果未能解决你的问题,请参考以下文章