Cyan Cyan - 3 months ago 7
C# Question

Correct way to run two tasks

I was wondering if this approach for running two long running operations in parallel and then getting their result is correct and if there would be any advantage to use async/await instead.

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;
}

Answer

Running tasks in parallel this way is fine. The WhenAll line does nothing and can be removed. Also note that Result will wrap any exceptions in AggregateException; this is normal when running parallel code.

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

  return res1.Result + res2.Result;
}

However, if the tasks are naturally asynchronous (e.g., I/O-bound), then you can do concurrent asynchronous code instead of parallel code:

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;
}

or, alternatively:

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

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