Cyan
Cyan

Reputation: 1108

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

Upvotes: 0

Views: 105

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456332

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

Upvotes: 3

Related Questions