【问题标题】:Use of async/await in console or web apps在控制台或 Web 应用程序中使用 async/await
【发布时间】:2016-06-17 20:53:48
【问题描述】:

据我了解,C# 中的async/await 功能将await 调用之间的段拆分为在每个等待的方法返回到单独的工作线程后在调用线程上运行的回调方法。调用线程在等待期间是“空闲的”。回调必须通过某种事件循环安排在调用线程上。

此事件循环仅存在于 GUI 应用程序(如 Windows 窗体或 WPF)中。释放此循环可确保 UI 在长时间操作期间对其他用户交互保持响应。

控制台应用程序和 Web 应用程序 (ASP.NET) 没有此类事件循环,因此此回调机制不起作用。但是话又说回来,他们没有事件循环,因为他们不需要。没有用户在任何时候试图与正在运行的程序进行交互,期望立即得到反馈。所以没有必要为此释放调用线程。操作使用多少线程无关紧要,它只会在最后一位完成后返回。

那么async 和await 在控制台和网络应用程序中的用途是什么,或者任何一般的非交互式代码,例如 Windows 服务?与简单的同步调用相比,这有何不同或更高效?

我正在设计一个供 GUI 和非交互式(服务和 Web)程序使用的 API,并且很难理解它在非 GUI 环境中的行为方式。

【问题讨论】:

  • 如果您不想在每个 IO 操作中使用一个线程,这仍然非常有用。如果处理得当,您可以通过异步处理数百个并发 IO 操作,而只需少量线程。

标签: c# .net multithreading async-await


【解决方案1】:

async-await 的要点是,当您到达第一个异步点(即未完成任务的第一个 await)时,调用线程总是被释放。

在 UI 应用程序中,您有一个 SynchronizationContext,它在等待后将代码发布到 UI 线程,因为与 UI 交互的代码必须由 UI 线程执行,否则您将收到异常。你可以使用ConfigureAwait(false)来控制它。

在控制台应用程序(和服务等)中没有这样的需要,因此代码在某个 ThreadPool 线程上运行。调用线程(很可能也是ThreadPool 线程)被释放并且能够同时执行其他类型的工作而不是同步阻塞。因此,async-await 提高了可扩展性,因为它可以使用相同数量的线程完成更多工作。

【讨论】:

  • 为了提高可扩展性,异步只对 I/O 密集型工作有用,对 CPU 密集型工作没有用,对吧?因为一个线程或另一个线程是否完成工作并不重要。仅在 I/O 操作完成时线程是被阻塞还是空闲并重新激活才重要。所以这意味着,我只需要在我的 API 中使用异步来进行 I/O 工作,而不一定需要长时间的计算。
【解决方案2】:

i3arnon's answer(和往常一样)非常出色。

那么,在控制台和 Web 应用程序中,或者任何类型的非交互式代码(例如 Windows 服务)中,async 和 await 有什么用处?

异步在客户端的主要好处是响应能力;服务器端异步的主要好处是可扩展性。

与简单的同步调用相比,这有何不同或更高效?

客户端响应能力和服务器端可扩展性是通过相同的机制实现的:释放调用线程。因此,异步就是使用更少的线程。在服务器端,使用更少的线程可以让您的应用最大限度地利用现有的线程池。

据我了解,C# 中的 async/await 功能将 await 调用之间的段拆分为回调方法,这些方法在每个等待的方法返回到单独的工作线程后在调用线程上运行。

这就是我要回答的原因。我就是放不下这个。这种理解每次提到“线程”都是错误的。这部分是正确的:await 将async 方法“拆分”为多个段。

1) 回调方法不在调用线程上运行。相反,await 将捕获“上下文”并在该上下文中恢复方法。特别是在 ASP.NET 应用程序和控制台应用程序上,上下文并不意味着特定的线程。我在async intro blog post 上详细解释了await 如何捕获上下文。

2) 异步 API 通常不会在工作线程上执行。异步的全部意义在于释放线程,因此阻塞线程池线程没有意义。我在 There Is No Thread 上的博客文章中解释了异步 I/O 几乎是无线程的。

【讨论】:

    【解决方案3】:

    Async/await 与多线程无关,引用MSDN:

    async 和 await 关键字不会导致额外的线程 创建的。异步方法不需要多线程,因为异步 方法不在自己的线程上运行。

    Async / await 允许您根据长时间运行的操作(可能是 CPU 工作或 I/O 工作)来构建代码。所以这适用于任何类型的程序(GUI、Web 服务、控制台等)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-12
      • 2015-05-04
      • 1970-01-01
      • 2014-06-20
      • 2017-06-16
      • 2015-08-10
      • 2019-12-26
      • 1970-01-01
      相关资源
      最近更新 更多