9

If I have a synchronous method "GetStrings()":

private static Task<string[]> GetStrings(IEnumerable<int> ids)
{
    var tasks = ids.Distinct().Select(GetString);
    return Task.WhenAll(tasks);
}

private static async Task<string> GetString(int stringId)
{
    await Task.Delay(15000);
    return "hello" + stringId;
}

(which itself calls async method "GetString()")

And I call this synchronous "GetStrings()" method from an async method:

public static async Task Main()
{
    var ids = new List<int> { 1, 2, 3 };
    await GetStrings(ids);
    Console.WriteLine("all done");
    Console.ReadLine();
}

What would be the behavioural difference, if GetStrings() was actually async? (and performed an await on the Task.WhenAll)

Would it simply stop Task.WhenAll from blocking the thread? I've found some production code which looks like this, so I've put together this small example to try and understand what's going. It's difficult to identify the difference though.

FaizanHussainRabbani
  • 3,256
  • 3
  • 26
  • 46
FBryant87
  • 4,273
  • 2
  • 44
  • 72

1 Answers1

10

Task.WhenAll doesn't block anyway, unlike Task.WaitAll. It just return a task that completes when all of the original tasks have completed.

It's important to understand that you don't await a method - you await a value (or some type that has to be awaitable). The await mechanism doesn't care how you obtained that value.

If GetStrings were async, there'd be one important difference: any exceptions thrown (e.g. if ids were null) would be result in a faulted task, whereas currently the exception would be thrown directly.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • So it's better to wrap it in `async await` i guess, right? – Ehsan Sajjad Feb 21 '18 at 13:06
  • 1
    @EhsanSajjad: Not necessarily. I wouldn't just do so without thinking. If the only reason for an exception is that there's a bug, finding that as early as possible is useful. – Jon Skeet Feb 21 '18 at 13:08