为什么要使用C#async/await来执行CPU限制的任务
我了解了C#中async/await关键字的诀窍,以及它们如何促进异步编程——允许线程在其他地方使用,同时执行一些I/O绑定任务,如db调用 我已经读过很多次,async/await用于I/O绑定的任务,而不是CPU绑定的任务。CPU绑定的任务应该在单独的后台线程上执行。在这些文章中多次提到。好的 但是,当使用为什么要使用C#async/await来执行CPU限制的任务,c#,multithreading,asynchronous,async-await,task-parallel-library,C#,Multithreading,Asynchronous,Async Await,Task Parallel Library,我了解了C#中async/await关键字的诀窍,以及它们如何促进异步编程——允许线程在其他地方使用,同时执行一些I/O绑定任务,如db调用 我已经读过很多次,async/await用于I/O绑定的任务,而不是CPU绑定的任务。CPU绑定的任务应该在单独的后台线程上执行。在这些文章中多次提到。好的 但是,当使用Task.Run在新线程上启动长时间运行的CPU绑定工作时,您必须在某个时间点等待它。那么,我们在这里不是也使用async/await来执行CPU限制的任务吗?见下面的例子 public
Task.Run
在新线程上启动长时间运行的CPU绑定工作时,您必须在某个时间点等待它。那么,我们在这里不是也使用async/await来执行CPU限制的任务吗?见下面的例子
public async Task SomeMethodAsync()
{
int result = await Task.Run(() =>
{
// Do lots of CPU bound calculations...
return result;
}
// Then do something with the result.
}
async/await
是进行异步编程的当代最简单的方法,无论作业是否受I/O限制;任务
是否需要线程
例如,这对于WinForms或WPF来说是非常好的,因为主线程可以等待子任务来计算Piggy小姐一年中吃午饭的次数(比方说,这是一个相当长且复杂的CPU限制操作),并且在完成时执行下面的下一行。它使您的代码非常直观,不像经典的异步回调WaitOne
s或其他机制以及与之配套的杂耍动作
MSDN:
通过使用异步编程,您可以避免性能瓶颈并增强应用程序的整体响应能力。然而,用于编写异步应用程序的传统技术可能非常复杂,难以编写、调试和维护
Visual Studio 2012引入了一种简化的方法,即异步编程,它利用了.NET Framework 4.5和Windows运行时中的异步支持编译器完成了开发人员过去所做的困难工作,,而您的应用程序保留了类似同步代码的逻辑结构
作品:
我已经读过很多次,async/await用于I/O绑定的任务
不对async/await
是异步编程的简写,在异步编程中,编译器会做更多的工作。它不仅仅适用于I/O绑定的任务。CPU绑定的任务通常使用线程池线程
CPU绑定的任务应该在单独的后台线程上执行
是的……但这并不意味着你不能等待任务
。CPU绑定的任务与I/O绑定的任务不同需要一个线程来操作,根据定义,工作线程,因此将从可用的线程池中获取一个
然而,当使用Task.Run在新线程上启动长时间运行的CPU绑定工作时,您必须在某个时刻等待它
你不必等待一个任务,这类任务被称为“开火遗忘”。等待
实际上也不会启动它,任务是“热的”。但是,如果不等待,则可能在应用程序退出时任务无法完成。e、 g.控制台应用程序启动任务
,不等待,然后退出
那么,我们在这里不是也使用async/await来执行CPU限制的任务吗
没错,您可以将它用于任何任务
,无论它是否为I/O绑定
更多
如果你等待
某件事,你有一个承诺,那就是你将从等待的操作中得到结果。通常,您希望等待的操作是异步\后台操作,该操作将在将来执行。同时,您可以继续您的工作,这可以独立于该操作的结果来完成
async/await
确实可以帮助编译器归档它await
将控件返回给调用方,并异步处理等待的操作。异步可以以不同的方式提供
一旦I/O操作进入内核空间,它们将被异步处理,所以您不需要为I/O操作创建额外的线程
在系统API调用之后,请求现在位于内核空间,使
它通向操作系统的网络子系统(如
Linux内核)。在这里,操作系统将处理网络请求
异步的。根据使用的操作系统的不同,详细信息可能会有所不同
设备驱动程序呼叫可以被安排为发送回设备的信号
运行时或设备驱动程序调用,然后发送信号
返回),但最终运行时将被告知
请求正在进行中。此时,设备驱动程序的工作已完成
将被安排、正在进行或已经完成
请求已经“通过连线”发出了-但因为这就是全部
异步发生时,设备驱动程序能够立即
处理其他事情
另一方面,对于CPU操作,您必须以某种方式指示CPU以异步方式进行操作,通常这是从不同的线程完成的(这就是您有Task.Run
)的原因)
CPU绑定异步代码与I/O绑定异步代码略有不同。
因为这项工作是在CPU上完成的,所以无法四处走动
将线程专用于计算。异步和等待的使用
为您提供了一种与后台线程和
使异步方法的调用方保持响应。请注意,这是正确的
不为共享数据提供任何保护。如果您使用的是共享
数据,您仍然需要应用适当的同步
战略
关键是,在这两种情况下,您都必须等待,以等待承诺的实现。关键是,在操作系统的核心中,I/O操作是异步的,当您调用内核时,它无论如何都是异步的,但对于CPU操作,您需要利用线程来指示CPU异步执行操作…您不必执行任务。运行到在新线程上执行。如果你等待并且