2016-08-17 58 views
0

我想知道如果这种方式并行运行两个长时间运行的操作,然后得到他们的结果是正确的,如果有任何优势,而不是使用异步/等待。正确的方式来运行两个任务

 public int DoStuff() 
     { 
      var res1 = Task.Run(() => LongRunning1()); 
      var res2 = Task.Run(() => LongRunning2()); 

      Task.WhenAll(res1, res2); 
      return res1.Result + res2.Result; 
     } 

     int LongRunning1() 
     { 
      Thread.Sleep(30); 
      return 10; 
     } 

     int LongRunning2() 
     { 
      Thread.Sleep(10); 
      return 20; 
     } 
+1

在这两个长时间运行的操作过程中还有其他事情吗? –

+2

长时间运行的IO或CPU是否受到限制? –

回答

4

以这种方式并行运行任务很好。 WhenAll行不执行任何操作,可以删除。还请注意,Result将在AggregateException中包含任何例外;运行并行代码时这是正常的。

public int DoStuff() 
{ 
    var res1 = Task.Run(() => LongRunning1()); 
    var res2 = Task.Run(() => LongRunning2()); 

    return res1.Result + res2.Result; 
} 

但是,如果任务自然是异步的(例如,I/O限制),那么你可以做并发异步代码,而不是并行代码:

async Task<int> LongRunning1Async() 
{ 
    await Task.Delay(30); 
    return 10; 
} 

async Task<int> LongRunning2Async() 
{ 
    await Task.Delay(10); 
    return 20; 
} 

public async Task<int> DoStuffAsync() 
{ 
    var res1 = LongRunning1Async(); 
    var res2 = LongRunning2Async(); 

    return await res1 + await res2; 
} 

,或者或者:

public async Task<int> DoStuffAsync() 
{ 
    var res1 = LongRunning1Async(); 
    var res2 = LongRunning2Async(); 

    var results = await Task.WhenAll(res1, res2); 
    return results[0] + results[1]; 
} 
+0

的任务是http请求。异步/等待仍然推荐?与.Result方法相比,有什么优势? – Cyan

+1

@Cyan:HTTP请求是I/O,所以是的,你应该使用异步并发而不是并行。好处是你使用更少的线程来完成相同的结果。 –

+0

还有一个问题@Stephen:你的博客在这里http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html你在说。结果会导致死锁。为什么不在上面的代码中? – Cyan

相关问题