2

I would like to populate a collection using collection initializer that will call async methods:

public class Diagnostics
{
    public async Task<IEnumerable<DiagnosticsInfo>> Get() => new List<DiagnosticsInfo>
    {            
        await GetDiagnosticsInfo1(),
        await GetDiagnosticsInfo2(),
        await GetDiagnosticsInfo3()
    };
}

The aim is for all the GetDiagnosticsInfoX() methods to execute in parallel. I have a suspicion that the generated code will invoke GetDiagnosticsInfoX() methods synchronously - it will await the first call before invoking the second.

Is my gut feel correct?

If so I assume I would need to await all the tasks like this:

public class Diagnostics
{
    public async Task<IEnumerable<DiagnosticsInfo>> Get()
    {
        var task1 = GetDiagnosticsInfo1();
        var task2 = GetDiagnosticsInfo2();
        var task3 = GetDiagnosticsInfo3();

        await Task.WhenAll(task1, task2, task3);

        return new List<DiagnosticsInfo> {task1.Result, task2.Result, task3.Result};
    }
}
1
  • 2
    Is my gut feel correct? yes. ;) Commented Nov 26, 2015 at 12:18

1 Answer 1

2

Is my gut feel correct?

Your gut feeling is right. All collection initializer does is invoke the Add method for the collection. This means your code is translated to:

public async Task<IEnumerable<DiagnosticsInfo>> Get()
{
    var list = new List<DiagnosticsInfo>();         
    list.Add(await GetDiagnosticsInfo1());
    list.Add(await GetDiagnosticsInfo2());
    list.Add(await GetDiagnosticsInfo3());
    return list;
}

Using Task.WhenAll will wait for all async methods to complete. You can then return the array you receive:

public async Task<IEnumerable<DiagnosticsInfo>> Get()
{
    var task1 = GetDiagnosticsInfo1();
    var task2 = GetDiagnosticsInfo2();
    var task3 = GetDiagnosticsInfo3();

    return await Task.WhenAll(task1, task2, task3);
}
Sign up to request clarification or add additional context in comments.

5 Comments

return await Task.WhenAll() - nice
i think removing return is enough.
@M.kazemAkhgary What do you mean?
return await not works. compile time error. cannot convert void to Collection.Generics blah blah
@M.kazemAkhgary It would only be void if the return value from GetDiagnosticsInfo is a Task, which it isn't. It's a Task<DiagnosticsInfo>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.