为什么使用C#async/await来处理CPU绑定的任务

Top*_*don 7 c# multithreading asynchronous task-parallel-library async-await

我正在使用C#中的async/await关键字,以及它们如何促进异步编程 - 允许在其他地方使用该线程,而某些I/O绑定任务如db调用正在进行中.

我已经多次读过async/await用于I/O绑定任务,而不是CPU绑定任务.CPU绑定任务应该在单独的后台线程上执行.在这些视频中多次提到过.一切都好.

但是,在使用新线程启动长时间运行的CPU绑定工作时Task.Run,您必须await在某个时刻使用它.那么我们不是也在这里使用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.
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*kyD 13

async/await无论工作是否受I/O约束,都是进行异步编程的当代和最简单的方法; 是否Task需要一个线程.

例如,它非常适合WinForms或WPF,因为主线程可以await通过子任务来计算Pig Piggy在一年中吃午餐的次数(相当长且复杂的CPU绑定操作),并且当完成执行下一个操作时紧接在下面.与传统的异步回调不同,它使您的代码非常直观; WaitOnes或其他机制以及与之相关的杂耍行为.

MSDN:

通过使用异步编程,您可以避免性能瓶颈并提高应用程序的整体响应能力.但是,编写异步应用程序的传统技术可能很复杂,使得编写,调试和维护变得困难.

Visual Studio 2012引入了一种简化的方法,即异步编程,它利用.NET Framework 4.5和Windows运行时中的异步支持.编译器执行开发人员过去所做的艰巨工作,并且您的应用程序保留了类似于同步代码的逻辑结构.更多...

OP:

我已多次读过async/await用于I/O绑定任务

不正确. async/await是异步编程的简写,编译器可以完成更多的工作.它不仅适用于I/O绑定任务.CPU绑定任务通常使用线程池线程.

CPU绑定任务应该在单独的后台线程上执行.

是的......但是,这并不意味着你不能awaitTask.与I/O绑定任务不同的CPU绑定任务需要一个线程来操作,并且根据定义工作线程,因此将从可用线程池中获取一个.

但是,当使用Task.Run在新线程上启动长时间运行的CPU绑定工作时,您必须在某个时刻等待它

你不必await一个Task,这样的任务将被称为发射后不管.在await实际上并没有启动,要么,任务是"热".但是,如果不等待,您将面临应用程序退出时未完成任务的风险.例如,一个控制台应用程序触发Task并且不等待它然后退出.

那么我们不是也在这里使用async/await来处理CPU绑定的任务吗?

没错,Task无论是否受I/O限制,您都可以使用它.

更多