3

What is the correct way to handle a part of code that you want to execute at the same time in C#? Each of these calls takes about 3 seconds each (we are making indexing improvements in our systems currently). How do I make these statements execute in parallel with results?

var properties = await _propertyService.GetPropertiesAsync("Fairfax, VA");

var ratings = await _ratingsService.GetRatingsAsync(12549);
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
BuddyJoe
  • 69,735
  • 114
  • 291
  • 466

2 Answers2

3

You can remove await from invocation and await for result of Task.WhenAll:

var propertiesTask = _propertyService.GetPropertiesAsync("Fairfax, VA");
var ratingsTask = _ratingsService.GetRatingsAsync(12549);
await Task.WhenAll(propertiesTask, ratingsTask);
var properties = propertiesTask.Result;
var ratings =  ratingsTask.Result;

Or split method invocation and awaiting (which is usually less preferable option):

var propertiesTask = _propertyService.GetPropertiesAsync("Fairfax, VA");
var ratingsTask = _ratingsService.GetRatingsAsync(12549);
var properties = await propertiesTask;
var ratings = await ratingsTask;
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • So does one style have an advantage over the other? I guess the first method is explicit (self-documenting). Any other pros or cons? – BuddyJoe Oct 28 '21 at 16:15
  • 2
    @GuruStron omitting the `await Task.WhenAll` means that if the first task fails, the second task will be leaked as a fire-and-forget task. Which is rarely what you want! – Theodor Zoulias Oct 28 '21 at 16:27
  • @BuddyJoe one major difference is exception handling. `Task.WhenAll` will aggregate all exceptions and propagate them to caller while in case of muiltiple `await`'s only the first faulted will be observed. – Guru Stron Oct 28 '21 at 16:28
  • 2
    @BuddyJoe also check out [this question](https://stackoverflow.com/questions/18310996/why-should-i-prefer-single-await-task-whenall-over-multiple-awaits) – Guru Stron Oct 28 '21 at 16:29
3

You can use Task.WhenAll for that.

Task.WhenAll will not block and can be awaited, yielding control back to the caller until all tasks finish (in contrast to Task.WaitAll)

In terms of exceptions, If any of the prvided tasks completes in a faulted state, then the returned task will also complete in a Faulted state, where its exceptions will contain the aggregation of the set of the unwrapped exceptions from each of the supplied tasks.

var task1 = _propertyService.GetPropertiesAsync("Fairfax, VA");
var task2 = _ratingsService.GetRatingsAsync(12549);

await Task.WhenAll(task1, task2);
Ran Turner
  • 14,906
  • 5
  • 47
  • 53