如何在不使用Task.Run的情况下编写异步兼容方法

时间:2015-01-15 00:20:53

标签: c# .net task-parallel-library async-await

重新编写我的SlowMethodAsync async方法的适当方法是什么,该方法执行长时间运行的任务,可以等待,但不使用Task.Run

我可以使用Task.Run执行以下操作:

public async Task SlowMethodAsync()
{
    await Task.Run(() => SlowMethod());
}

public void SlowMethod()
{
    //heavy math calculation process takes place here
}

如上所示,代码将从线程池中生成一个新线程。如果它可以以不同的方式完成,它将在调用线程上运行,并以任何方式阻止它,因为SlowMethod内容是一个坚实的数学处理块,没有任何屈服和时间片放弃。

只是为了澄清我需要我的方法保持异步,因为它解除了我的UI线程。只是寻找另一种可能的方式,以不同的方式完成它当前的工作方式,同时保持异步方法签名。

2 个答案:

答案 0 :(得分:4)

async方法适用于异步操作。它们不会阻止线程用于非CPU绑定的工作。如果您的SlowMethod有任何当前同步执行的IO绑定操作(例如Stream.ReadSocket.Send),您可以将这些操作交换为asyncawaitasyncThreadPool方法中。

在你的情况下(数学处理)代码可能主要是CPU绑定的,所以除了将工作卸载到Task.Run线程(使用async)之外,没有理由使用SlowMethod所有。 保持Task.Run不变,它将在调用线程上运行。


关于您的更新:您肯定希望使用Task.Factory.StartNew(或其中一个{{1}}重载)将您的工作卸载到其他线程。

答案 1 :(得分:2)

实际上,对于您的具体情况,您应该使用

await Task.Factory.StartNew(() => SlowMethod(), TaskCreationOptions.LongRunning)

这将允许调度程序在适当的位置(可能在新线程中)运行同步任务,因此它不会使ThreadPool(它不是真正为CPU繁重的工作负载设计)。

同步拨打SlowMethod会不会更好?你在等待它获得了什么?