我一直在阅读 C# 中新的 async
和 await
运算符,并试图找出它们在哪些情况下可能对我有用。我研究了几篇 MSDN 文章,下面是我在字里行间读到的内容:
您可以对 Windows 窗体和 WPF 事件处理程序使用 async
,这样它们就可以执行冗长的任务,而不会在执行大量操作时阻塞 UI 线程。
async void button1_Click(object sender, EventArgs e)
{
// even though this call takes a while, the UI thread will not block
// while it is executing, therefore allowing further event handlers to
// be invoked.
await SomeLengthyOperationAsync();
}
使用 await
的方法必须是 async
,这意味着在代码中某处使用任何 async
函数最终会强制所有方法进入从 UI 事件处理程序到最低级别的 async
方法的调用顺序也是 async
。
换句话说,如果您使用普通的旧ThreadStart
入口点创建线程(或使用旧的static int Main(string[] args)
),那么你就不能使用 async
和 await
,因为在某一时刻你必须使用 await
,并使使用它的方法 async
,因此在调用方法中您还必须使用 await
并使其成为 async
等等。但是,一旦到达线程入口点(或 Main()
),就没有 await
会向其屈服控制的调用者。
因此,如果没有使用标准 WinForms 和 WPF 消息循环的 GUI,基本上您无法使用 async
和 await
。我想这一切确实有道理,因为 MSDN 声明 async
编程并不意味着多线程,而是使用 UI 线程的空闲时间;当使用控制台应用程序或具有用户定义入口点的线程时,多线程将是执行异步操作所必需的(如果不使用兼容的消息循环)。
我的问题是,这些假设是否准确?
最佳答案
So basically you cannot use async and await without having a GUI that uses the standard WinForms and WPF message loop.
绝对不是这样的。
在 Windows 窗体和 WPF 中,async
/await
具有在您等待的异步操作完成时返回到 UI 线程的便利属性,但这并不这意味着这是它的唯一目的。
如果异步方法在线程池线程上执行 - 例如在 Web 服务中 - 然后继续(异步方法的其余部分)将简单地在任何线程池线程中执行,并适当保留上下文(安全等)。这对于减少线程数仍然非常有用。
例如,假设您有一个高流量网络服务,它主要代理对其他网络服务的请求。它花费大部分时间等待其他事情,无论是由于网络流量还是其他服务(例如数据库)的真实时间。你不应该为此需要很多线程——但是通过阻塞调用,你自然会为每个请求得到一个线程。使用 async/await,您最终会得到很少的线程,因为很少有请求实际上需要在任何时间点为它们执行任何工作,即使有很多请求也是如此”在飞行中。
问题是 async/await 最容易用 UI 代码演示,因为每个人都知道正确使用后台线程或在 UI 线程中做太多工作的痛苦。这并不意味着它是该功能唯一有用的地方 - 远非如此。
各种服务器端技术(例如 MVC 和 WCF)已经支持异步方法,我希望其他人也能效仿。
关于c# - async 和 await 是否专用于基于 GUI 的异步编程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12654968/