为了账号安全,请及时绑定邮箱和手机立即绑定

应该在另一个任务中使用 Task.Run 吗?

应该在另一个任务中使用 Task.Run 吗?

C#
慕的地6264312 2022-01-09 14:33:32
我有一堆工作要做(CPU 密集型或 IO 密集型,没有异步接口可用)。我想知道是否可以像这样在任务中完成所有非异步工作:async Task DoSomeStuff(){    await SomethingAsync();    …    DoCpuBoundWork();    …    await SomethingElseAsync();}或者我应该像这样使用 Task.Run 吗?async Task DoSomeStuff(){    await SomethingAsync();    …    await Task.Run(() => DoCpuBoundWork());    …    await SomethingElseAsync();}我知道任务不一定在另一个线程上执行,所以我想知道调度程序是否会假设任务是非阻塞的,这将使在 Task.Run 之外执行 CPU 密集型工作减慢应用程序的速度。例如,如果调度程序决定将受 CPU 限制的工作调度到应用程序的 UI 线程,则可能会变慢。我确定以前有人问过这个问题,但是我找不到合适的关键字来搜索它,对此感到抱歉。
查看完整描述

2 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

正如指出的这个页面(部分更加深入地了解任务和任务<T>的CPU绑定的操作),任务从他们被称为线程上运行,而CPU限制的工作其实应该被包裹在一个Task.Run如此它”将在另一个(后台)线程上运行。所以,是的,在异步方法中使用 Task.Run 来进行 CPU 绑定或其他阻塞工作是正常且正常的。从页面引用:


public async Task<int> CalculateResult(InputData data)

{

    // This queues up the work on the threadpool.

    var expensiveResultTask = Task.Run(() => DoExpensiveCalculation(data));


    // Note that at this point, you can do some other work concurrently,

    // as CalculateResult() is still executing!


    // Execution of CalculateResult is yielded here!

    var result = await expensiveResultTask;


    return result;

}

CalculateResult() 在调用它的线程上执行。当它调用 Task.Run 时,它会将昂贵的 CPU 绑定操作 DoExpensiveCalculation() 排入线程池并接收一个任务句柄。DoExpensiveCalculation() 最终在下一个可用线程上并发运行,可能在另一个 CPU 内核上。当 DoExpensiveCalculation() 忙于另一个线程时,可以进行并发工作,因为调用 CalculateResult() 的线程仍在执行。


一旦遇到 await,CalculateResult() 的执行就交给它的调用者,允许在 DoExpensiveCalculation() 生成结果时使用当前线程完成其他工作。完成后,结果将排队等待在主线程上运行。最终,主线程将返回执行CalculateResult(),此时它将得到DoExpensiveCalculation() 的结果。


查看完整回答
反对 回复 2022-01-09
?
冉冉说

TA贡献1877条经验 获得超1个赞

答案是:视情况而定。

您指出了调度程序,这正是问题所在。如果您在线程池(默认调度程序)上运行,那么运行同步的 CPU 密集型工作非常好。如果你在 UI 线程上运行,这可能会导致糟糕的用户体验。

也就是说,虽然这是一个问题,但这不是你的问题。您的合同已实施DoSomeStuff,您将在当前调度程序上运行一些工作。由调用者决定这是否可能是一个问题,在这种情况下添加一个Task.Run以抵消对另一个调度程序的调用。

简而言之,不要使用await Task.Run(() => DoCpuBoundWork());. 让知道执行上下文的调用者为您决定。


查看完整回答
反对 回复 2022-01-09
  • 2 回答
  • 0 关注
  • 176 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信