Асинхронное заполнение инициализатора коллекции

Я хотел бы заполнить коллекцию, используя инициализатор коллекции, который будет вызывать асинхронные методы:

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

Цель для всех GetDiagnosticsInfoX() методы выполнять параллельно. У меня есть подозрение, что сгенерированный код будет вызывать GetDiagnosticsInfoX() методы синхронно - он будет ожидать первого вызова перед вызовом второго.

Моя кишка чувствует себя правильно?

Если это так, я предполагаю, что мне нужно будет подождать все такие задачи:

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 ответ

Решение

Моя кишка чувствует себя правильно?

Ваше внутреннее чувство верно. Все, что делает инициализатор коллекции - это вызывает Add метод для коллекции. Это означает, что ваш код переведен на:

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

С помощью Task.WhenAll будет ждать завершения всех асинхронных методов. Затем вы можете вернуть полученный массив:

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

    return await Task.WhenAll(task1, task2, task3);
}
Другие вопросы по тегам