任务处理的差异

时间:2016-05-20 19:00:58

标签: c# .net async-await

让我们假设我有两种方法,比如......

public void MyMethod()
{
    // do some stuff
}

public Task MyMethodAsync()
{
    //run MyMethod asynchronously
}

以异步方式执行它的最佳形式是什么?

喜欢这个

public Task MyMethodAsync()
{
    return Task.Run(() => MyMethod());
}

还是喜欢这个?

public async Task MyMethodAsync()
{
    await Task.Run(() => MyMethod());
}

3 个答案:

答案 0 :(得分:3)

您应该在何时使用Task.Run时阅读Stephen Cleary's tutorial

简短回答:不要使用Task.Run来创建虚假的异步方法。如果您的代码不是真正的异步,那么让调用者决定是否应使用线程(或其他)来调用您的代码。

答案 1 :(得分:1)

最好还是走另一条路。将内部任务构建为异步,然后让所有不能使用异步方法的调用者在内部使用异步,并等待它。

public void MyMethod()
{
    MyMethodAsync().Wait();
}

public async Task MyMethodAsync()
{
    // do some stuff
}

你的两种方法都没有真正做出任何异步。异步不是关于在后台运行某些东西,这是任务库(或并行扩展,或线程等)的领域。 Async是关于能够在没有更好的事情的情况下为多个事情重用单个线程 - 这使事情更具可扩展性。制作伪异步方法只是隐藏了一个事实,即您正在使用新线程而不是重用相同的线程,这使得系统LESS可扩展。

为了做到这一点,真正的异步进程需要从内到外编写。一切(或至少是耗时的部分)需要依赖于那样做的异步方法。例如,在等待调用返回,数据库调用或文件I / O时,进行SOAP调用,其中线程基本上处于空闲状态。 Async允许该线程执行其他有用的操作而不是闲置。

答案 2 :(得分:1)

对于第一种方法,您也可以在单独的线程上执行任务。它并不是真正的异步,因为你没有明确地等待线程结束以启动新进程。如果你打电话给它,它将在任务完成之前继续。

public Task MyMethodAsync()
{
    return Task.Run(() => MyMethod());
}

看第二个版本。您正在等待任务完成,以便您可以在不占用当前线程的情况下执行某些操作。

public async Task MyMethodAsync()
{
    await Task.Run(() => MyMethod());
    DoMoreWork();
    //Do something following the completion of the task 
     //without binding up the calling thread, but actually complete it on that thread.
}