【问题标题】:How does await async work in C# [closed]等待异步如何在 C# 中工作 [关闭]
【发布时间】:2013-07-03 13:04:21
【问题描述】:

我试图了解等待异步在 C# 中的工作原理,但有一件事让我很困惑。我知道任何使用 await 关键字的方法都必须用 async 标记。 我的理解是,当点击带有 await 关键字的行时,该行下面的代码不会被执行。启动异步操作以执行 await 行中的语句,并将控制权返回给可以继续执行的调用方法。

问题#1:这个假设是正确的还是await关键字下面的代码仍然被执行?

其次假设我调用了一个服务方法异步并且需要返回它的结果。 return 语句位于 await 关键字下方。

问题 #2:return 语句何时命中,在异步调用完成之后还是之前?

问题 #3:我想使用该服务调用的结果,而异步操作无济于事,因为我希望在返回结果时调用调用方法。我知道这可以使用使调用同步的 Result 属性来完成。但是在数据库操作中使用异步有什么用,因为它们实际上在大多数应用程序中占用了 80% 的时间。

问题 #4:如何将异步与数据库操作一起使用?有可能并推荐吗?

问题#5:异步操作在哪种情况下有用,似乎每个api现在都在无缘无故地进行异步操作?还是我错过了使用异步操作的意义?

我的意思是说 api 无缘无故地制作 asyn 方法是因为方法必须返回一些东西,直到计算出来它们如何返回,所以从本质上讲,调用不会在某种意义上仍然阻塞在返回结果之前没用?

【问题讨论】:

  • 你问了很多问题。如果您只问一个重点问题,那么 SO 效果最好。如果您有多个问题,请分别发布。
  • @Svick 我看到它的方式 MDSN 让我更加困惑,并在我的脑海中留下了很多问题。如果其他人有同样的问题,也许他们可以看到这个线程并更好地理解异步操作。我所有的问题都与一个主题有关,对我来说,发布 5 个不同的问题并希望有人能看到所有这些问题是没有意义的......
  • 所以是关于分享你的知识,对吧?唯一的规则是问题应该是准确和可回答的。
  • @SyedAfrazAliRizvi 发布多个问题的问题在于,一个人可能会回答您的一些问题,而另一个人可能会回答您的部分问题。在那种情况下,你如何判断应该接受哪个答案?

标签: asynchronous async-await c#-5.0


【解决方案1】:

MSDN explains everything.

虽然我理解有时原版文档(尤其是来自 MSDN)可能难以适用于您的特定情况,所以让我们回顾一下您的观点。

问题#1:这个假设是正确的还是await关键字下面的代码仍然被执行?

“await”关键字下面的代码只会在异步调用完成时执行。同时,由于您的方法被标记为“异步”,因此控制权将返回给您的方法的调用者,直到您的方法完成。 从上面的 MSDN 链接:

Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();

// The await operator suspends AccessTheWebAsync. 
//  - AccessTheWebAsync can't continue until getStringTask is complete. 
//  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
//  - Control resumes here when getStringTask is complete.  
//  - The await operator then retrieves the string result from getStringTask. 
string urlContents = await getStringTask;

我认为 cmets 很能说明问题。

其次,假设我调用了一个服务方法 async 并且需要返回它的结果。 return 语句位于 await 关键字下方。

问题 #2:return 语句何时命中,在异步调用完成之后还是之前?

之后。

问题 #3:我想使用该服务调用的结果,而异步操作无济于事,因为我希望在返回结果时调用调用方法。我知道这可以使用使调用同步的 Result 属性来完成。但是在数据库操作中使用异步有什么用,因为它们实际上在大多数应用程序中占用了 80% 的时间。

假设您需要进行三个不相关的数据库查询来完成您的服务,然后根据结果进行计算,然后完成。如果您按顺序执行此操作,则必须等到每个操作完成。如果您使用异步调用,则 C# 将并行运行三个查询,您的服务可能会更快完成。

此外,返回 Task 的操作可以用作 Futures。请参阅MSDN on Futures,其中讨论了几种模式,了解如何基于期货并行化工作并合并结果。

如果您的服务只需要一次 DB 调用,那么将其称为异步肯定会更糟。

问题 #4:如何将异步与数据库操作一起使用?是否可行并推荐?

ADO.NET 现在包括异步方法 ReadAsync and NextResultAsync

绝对有可能,至于推荐这个讨论比我写的here要完整得多。

问题#5:异步操作在哪种情况下有用,似乎每个api现在都在无缘无故地进行异步操作?还是我错过了使用异步操作的意义?

异步操作对于轻松并行化任何长时间运行的操作而不会遇到线程问题非常有用。如果您的方法只做一件事,或者一系列简单(快速)的事情,那么是的,异步是没有用的。但是,如果您有多个长时间运行的操作,则通过异步将它们并行化比管理线程要容易得多且不易出错。

【讨论】:

  • 哇!谢谢队友,你以非常容易理解的方式解释了一切。我浏览了 MSDN,但我看到了一张图表,上面有很多数字,解释了何时执行哪一行,这让我更加困惑。感谢您的回复!
  • 您引用的代码引用了未定义/包含在引用代码中的“AccessTheWebAsync”。假设它是容器方法。
【解决方案2】:

您的大部分问题都在我写的officialdocumentationan intro post 中得到解答。

问题 #4:如何将异步与数据库操作一起使用?有没有可能

Entity Framework 6(目前处于测试阶段)支持async。较低级别的数据库 API 以一种或另一种方式支持异步操作。其中一些(例如,SQLite)直接支持async;其他人需要你编写简单的async-compatible 包装器。

...并推荐?

是的,除非您正在编写与后端不可扩展的单一数据库机器通信的前端服务器(例如 ASP.NET)。在这种特定情况下,使您的前端扩展没有意义,因为您的后端无论如何都无法扩展以匹配它。

问题#5:异步操作在哪种情况下有用,似乎每个api现在都在无缘无故地进行异步操作?还是我错过了使用异步操作的意义?

异步操作的好处是:

  1. 在客户端 (UI) 端,您的应用程序保持响应。
  2. 在服务器端,您的应用程序可以更好地扩展。

【讨论】:

  • 答案结尾处简单但完美陈述的好处。
猜你喜欢
  • 1970-01-01
  • 2021-12-20
  • 2020-01-03
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
相关资源
最近更新 更多