为什么要对CPU绑定的任务使用C#异步/等待 [英] Why use C# async/await for CPU-bound tasks

查看:87
本文介绍了为什么要对CPU绑定的任务使用C#异步/等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在C#中使用async/await关键字,并了解它们如何促进异步编程-允许线程在其他诸如db调用之类的I/O绑定任务进行时在其他地方使用.

I'm getting the hang of the async/await keywords in C#, and how they facilitate asynchronous programming - allowing the the thread to be used elsewhere whilst some I/O bound task like a db call is going on.

我已经读过很多遍了,异步/等待是针对I/O绑定的任务,而不是CPU绑定的任务.与CPU绑定的任务应在单独的后台线程上执行.在这些视频中多次提及.很好.

I have read numerous times that async/await is for I/O bound tasks, not CPU-bound tasks. CPU-bound tasks should be performed on a separate background thread. Mentioned several times in these videos. All ok.

但是,当使用 Task.Run 在新线程上开始长时间运行的CPU绑定工作时,则必须在某个时候 await .那么,我们不是也将async/await用于CPU绑定的任务吗?参见下面的示例.

However, when starting long-running CPU-bound work on a new thread using Task.Run, you then have to await it at some point. So aren't we using async/await here for a CPU-bound task too? See example below.

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 是进行 async 编程的现代且最简单的方法,无论工作是否I/O绑定; Task 是否需要线程.

async/await is the contemporary and easiest way to do async programming whether or not the job is I/O-bound; whether or not the Task requires a thread.

例如,对于WinForms或WPF来说,它非常有用,因为主线程可以等待一个子任务来计算Piggy小姐一年中吃午餐的次数(相当长且复杂的CPU,绑定操作),完成后立即执行下面的下一行.与传统的异步回调不同,它使您的代码如此直观. WaitOne 或其他机制以及随之而来的杂耍行为.

For example, it is great for WinForms or WPF because the main thread can await a child task to calculate the number of times Miss Piggy had lunch in a year (a rather long and complex CPU-bound operation let's say) and when complete executes the next line immediately below. It makes your code so intuitive unlike classical async callbacks; WaitOnes or other mechanisms and the juggling acts that go with it.

MSDN:

通过使用异步编程,可以避免性能瓶颈并增强应用程序的整体响应能力.但是,用于编写异步应用程序的传统技术可能会复杂,从而使其难以编写,调试和维护.

You can avoid performance bottlenecks and enhance the overall responsiveness of your application by using asynchronous programming. However, traditional techniques for writing asynchronous applications can be complicated, making them difficult to write, debug, and maintain.

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

Visual Studio 2012 introduces a simplified approach, async programming, that leverages asynchronous support in the .NET Framework 4.5 and the Windows Runtime. The compiler does the difficult work that the developer used to do, and your application retains a logical structure that resembles synchronous code. More...

OP:

我已经无数次地了解到异步/等待是针对I/O绑定任务的

I have read numerous times that async/await is for I/O bound tasks

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

Incorrect. async/await is shorthand for async programming where the compiler does more of the work. It is not just for I/O-bound tasks. CPU-bound tasks generally use a thread pool thread.

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

CPU-bound tasks should be performed on a separate background thread.

是的...但这并不意味着您不能等待 任务.与I/O绑定任务不同,与CPU绑定的任务需要一个线程才能运行,并且根据定义,它是 worker线程,因此将从可用线程池中抢占一个线程.

Yes...but that doesn't mean you can't await the Task. CPU-bound tasks unlike I/O-bound tasks require a thread to operate and by definition a worker thread and so will grab one from the available thread pool.

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

However, when starting long-running CPU-bound work on a new thread using Task.Run, you then have to await it at some point

您不必等待一个 Task ,这样的任务被称为即发即忘. await 也不实际启动它,任务是热"的.但是,如果不等待,则存在在应用程序退出时任务未完成的风险.例如控制台应用程序触发 Task ,然后不等待它,然后退出.

You don't have to await a Task, such tasks would be known as fire-and-forget. The await doesn't actually start it either, tasks are "hot". However by not awaiting, you run the risk of the task not completing when the application exits. e.g. a console app firing off a Task and not awaiting it then exiting.

所以我们也不在这里使用async/await来执行CPU受限的任务吗?

So aren't we using async/await here for a CPU-bound task too?

是的,您可以将其用于任何 Task ,无论它是否受I/O约束.

That's right, you can use it for any Task whether it is I/O-bound or not.

这篇关于为什么要对CPU绑定的任务使用C#异步/等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆