如何处理异步 I/O 方法

How are asynchronous I/O methods processed

在阅读了大量有关 async-await 的内容后,我只能发现在 GUI 线程中使用它的好处 (WPF/WinForms)。

在什么场景下减少WCF服务中线程的创建? 程序员是否必须通过选择在 Web 服务中实现异步等待来在服务中的每个方法 上使用异步等待 ?在充满异步等待的服务中制作一些非异步等待方法会降低我的服务效率?怎么样?

最后一个问题 - 有人说使用 'await Task.Run(()=>...)' 不是 "real async-await"。他们这么说是什么意思?

提前致谢, 斯塔夫

编辑:

两个答案都很好,但对于关于 async-await 如何工作的更深入的解释,我建议在这里阅读@Stephen Cleary 的答案:

要理解他的回答,需要以下主题: SynchronizationContext,SynchronizationContext.Current,TaskScheduler,TaskScheduler.Current,线程池。

async/await 在服务器应用程序(如 WCF)中的真正好处是异步 I/O。

当您调用同步 I/O 方法时,调用线程将被阻塞,等待 I/O 完成。该线程不能被其他请求使用,它只是等待结果。当更多的请求到来时,线程池会创建更多的线程来处理它们,浪费大量的资源——内存,等待线程解锁时的上下文切换...

如果使用async IO,线程不会被阻塞。启动异步IO操作后,就可以再次被线程池使用了。当异步操作完成后,线程池分配一个线程继续处理请求。没有资源浪费。

来自 MSDN(关于文件 I/O,但也适用于其他文件)

In synchronous file I/O, a thread starts an I/O operation and immediately enters a wait state until the I/O request has completed. A thread performing asynchronous file I/O sends an I/O request to the kernel by calling an appropriate function. If the request is accepted by the kernel, the calling thread continues processing another job until the kernel signals to the thread that the I/O operation is complete. It then interrupts its current job and processes the data from the I/O operation as necessary.

现在您可能明白为什么如果任务中的 IO 是同步完成的,await Task.Run() 不会带来任何好处。一个线程无论如何都会被阻塞,只是不会调用 Task.Run().

您不需要异步实现每个方法就能看到性能的提高(尽管总是异步执行 I/O 应该成为一种习惯)。

In what scenarios does it reduce the creation of threads in WCF services?

如果您有一个等待 IO 操作的操作(从数据库读取、调用外部 Web 服务,...),使用 async/await 释放您的 WCF 请求所在的托管线程正在处理中。这使得线程可用于其他请求,等待您的 IO 完成。它可以更有效地使用线程池。

After reading alot about async-await, I can only find the benefits of using it in GUI thread

对于 client 应用程序,这是我所知道的主要好处,因为您 运行 离开受管线程的可能性远小于您处于受管线程中的可能性服务器应用程序。

some say that using 'await Task.Run(()=>...)' is not a "real async-await".

您为 运行 您的新任务分配了一个新的托管线程,因此您没有保存任何托管线程。