2015-11-20 33 views
3

我对c#async/await机制有一些误解。 有什么时候多重等待有意义?

private async void Init() 
{ 
    await Task.Run(() => Do1()); 
    await Task.Run(() => Do2()); 
} 

private async void Init() 
{ 
    await Task.Run(() => 
    { 
     Do1(); 
     Do2(); 
    }); 
} 

我看到的唯一的区别之间的本质区别:第一个样品在D01和D02会在不同的线程来运行,而第二个样品中 - 在同一线。但是,再次,它的真正好处是什么,当我更喜欢第一种方法而不是第二种方法时,反之亦然?


编辑:第二种情况

是什么

private async void Init() 
{ 
    await Task.Run(() => Do1()); 
    Do3(); 
} 

private async void Init() 
{ 
    await Task.Run(() => 
    { 
     Do1(); 
     Do3(); 
    }); 
} 
+0

在你的具体情况下,第二种方法更好。因为Do1之后的任何方式,Do2将被执行,所以结果没有区别。 task.run在第一种方法中增加了一些开销。还要注意的是,在两种情况下,Do1都会先运行,然后在第一种情况下Do2启动 –

+0

@ M.kazemAkhgary,当任务正在启动时,它们是否会一个接一个地运行,然后我们马上等待?即,如果它们被分配给变量并在等待第一个变量之前启动它们,它们是否会同时运行? – Dhunt

+0

是的。如果您将它们存储在变量中,然后等待它们单独运行,但现在因为在创建任务之后等待它们开始一个接一个@Dhunt –

回答

3

的区别是:

第一个例子:

  • 您排队Do1一个线程池线程并异步等待它完成,然后与Do2完全相同。这些可能运行在不同的线程上。
  • 排队Do1Do2在同一个线程池线程上一个接一个地同步执行。

第二个例子:

  • 队列Do1上线程池和异步等待它完成,然后调用Do3同步。
  • 这与第一个例子的第二部分完全相同。

请注意,当你await,你异步等待操作完成,因此,除非方法完成,它不会执行下一行代码。

我假设你问自己,如果一个人比另一个人更好,并且在大多数情况下,这取决于。如果您正在控制台应用程序中运行,并且您将异步等待Do1完成,则将这两种方法都传递给相同的Task.Run调用。如果您打算在同步很重要的地方(例如GUI应用程序)执行此操作,则需要在UI线程上调用需要与UI控件交互的任何操作。

另一种更常见的选择是当您有两个彼此独立的操作,并且您希望一起启动它们并等待两者完成时。在这里,你会使用Task.WhenAll

var firstDo = Task.Run(() => Do1()); 
var secondDo = Task.Run(() => Do2()); 
await Task.WhenAll(firstDo, secondDo); 

旁注:

不要在异步方法使用async void没有返回值,这就是async Task是。前者只是为了与事件处理程序兼容,我假设事实并非如此。

0
  • 如果Do1()Do2()是相互独立的,你应该运行它们之间的区别分别。如果它们是长时间运行/阻塞进程,则这更为重要
  • 另一方面,如果它们是相关的,并且第一个执行另一个所需的某些操作,那么最好在一个线程中运行它们以减少线程开销。毕竟,你事先知道他们需要运行顺序
+0

在这两种情况下,它们都运行另一个。我看到的唯一区别是:在第一种情况下,它们将在各自的线程中运行。但不是同时!第二项任务的线程将在第一项任务完成后启动。所以除了一些性能开销之外,我没有看到这些情况之间的任何本质区别。 – Sergey

相关问题