何时使用异步和等待 - 客户端与 webapi [关闭]

Posted

技术标签:

【中文标题】何时使用异步和等待 - 客户端与 webapi [关闭]【英文标题】:When to use async and await - client vs webapi [closed] 【发布时间】:2019-10-25 03:25:41 【问题描述】:

我正在使用 ASP.NET Web Api 构建一个规划器,它目前在其中执行一些简单的 CRUD 操作。此 API 的主要目的之一是能够接受来自不同平台(Web 和 android 应用程序客户端)的请求。我的问题是关于 async 和 await 和 web api 的最佳实践(以及什么是有意义的)——我应该在哪里提供异步?在客户端级别还是在 API 级别(服务器)?

我知道 async 和 await 的主要目的之一是为 UI 提供响应能力。而且我知道异步模型主要涵盖 I/O 绑定或 CPU 绑定操作。我猜从这个意义上说,我的进程会受到 I/O 限制。但最佳实践是明智的,API 应该是异步的还是应该保留在客户端中?我的 api 将在 Azure 的应用服务上运行。

以下是我的 API 中的示例“获取”操作(同步代码而非实际代码):

[Authorize]
[Route("GetUser/userId")]
public IHttpActionResult GetUser(int userId)

    return Ok(/* method calls are done here... */);

我提出的异步示例:

[Authorize]
[Route("GetUser/userId")]
public async Task<IHttpActionResult> GetUser(int userId)

    return Ok(await /* method calls are done here... */);

我正在使用 HttpClient 向 api 发出请求。

我的期望是多个人将使用该客户端。所以我会假设客户端应该是异步的,并且 api 可以保持同步。但同样,我试图弄清楚这里最好的做法是什么(明智的最佳实践)。

【问题讨论】:

为什么你认为只有一个应用程序可以使用异步操作?单独处理每个应用程序。如果该应用程序正在执行异步操作,请异步执行。 服务器端,使用async 可以让您处理更多请求(从而实现可扩展性)。在 客户端,使用async 将释放 UI 线程(假设它是发出请求的线程),而操作系统正在等待位到达(因此您实现 响应能力) 所以@haim770 你是说一直异步? @Jae,这取决于您的需求。如果您期望服务器上的高负载并且它主要执行 IO,那么async 是一个合理的选择。无论如何,您必须意识到客户端使用异步 http 的事实并不意味着服务器也必须是异步的。即使服务器阻塞了自己的线程,你的 UI 仍然可以响应,并且无论客户端是否异步,服务器中的线程池仍然可以重用工作线程。 酷,谢谢@haim770,说得通。 【参考方案1】:

既然您已经要求最佳做法,请一直采用异步方式。 当您尝试使其以同步方式工作时,异步只会变得复杂(并给您带来麻烦)。一路异步(用 asp.net core 很容易做到),你会很好。

来源:https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md

(如果 API 操作本质上没有执行任何异步操作,您可以在该 API 上保留异步,但默认为异步。)

【讨论】:

我想这对 scabality 来说是有道理的。但是你的意思到底是什么:“如果一个 API 操作本质上没有做任何异步操作,你可以在那个 API 上保留异步,但默认为异步。”您是说如果该方法本质上是同步的,那么就保持原样? @Jae 是的。基本上默认情况下使所有内容异步,如果不需要,则将其排除在外。不是相反。 感谢 AsyncGuidance @gldraphael @Jae 非常感谢 David Fowler 和其他为此做出贡献的人。【参考方案2】:

因为它是一个网络服务器,所以没有线程负责更新 UI,就像在本地应用程序中一样。所以这并不是真正的考虑因素。

async/await 在 Web 服务器中的主要优点是,当您等待长时间的 I/O 操作时,线程被释放以执行其他任务。如果您的 Web 服务器确实受到重创,例如 100 次点击/秒,并且它正在使用其线程池中的每个线程,那么新的 Web 请求必须等到一个线程被释放才能被处理。

如果您没有受到那么严重的打击和/或您没有相对较长的 I/O 操作,那么您的第一个代码 sn-p 就可以了,您无需深入研究 async/await 的复杂性.但是,在客户端,您应该使用异步来执行这些 Web 服务器调用,因为它们是 I/O 调用并且可能会阻塞 UI 线程。

【讨论】:

啊,好的,所以基本上你所说的是,在 api 方面,除非我遇到高流量,否则不需要异步。但在客户端,它是一个明确的(UI 响应性和所有)。 是的。 @haim770 在 cmets 中措辞简洁明了。

以上是关于何时使用异步和等待 - 客户端与 webapi [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript(异步)如何确定在继续之前要“等待”啥?

JavaScript 何时同步?

什么是“异步 Request-Reply”模式?编程如何实现?

何时在Python中使用等待键?

异步与线程,何时使用每个选项?

异步接受传入请求