Одновременный запуск асинхронных методов

Имеет смысл выделять асинхронные методы в отдельные задачи, с целью одновременного начала работы всех методов и ожидание самого последнего перед продолжением работы основного потока?

Например 3 асинхронные задачи:

var users = await _db.Users.ToListAsync();
var additionalInfo = await _client_api.GetAsync(request_to_additional_api);
var weather = await _client.GetAsync(request_to_weather_api);

users.ToList().ForEach(u=>u.AdditionalInfo = additionalInfo.Where(ai=>ai.UserId == u.Id));
var resultDataViewModel = new ResultDataViewModel{
    Users = users ,
    Weather = weather 
};

Имеет смысл создать для них 3 отдельных таска?

Task[] tasks = new Task[3];
IEnumerable<User> users = null;
AdditionalInfo additionalInfo =null;
Weather weather =null;
tasks[0] = Task.Run(async=> {
    users = await _db.Users.ToListAsync();
});
tasks[1] = Task.Run(async=> {
    additionalInfo = await _client_api.GetAsync(request_to_additional_api);
});
tasks[2] = Task.Run(async=> {
    weather = await _client.GetAsync(request_to_weather_api);
});
Task.WaitAll(tasks);

users.ToList().ForEach(u=>u.AdditionalInfo = additionalInfo.Where(ai=>ai.UserId == u.Id));
var resultDataViewModel = new ResultDataViewModel{
    Users = users ,
    Weather = weather 
};

Если бы методы были синхронными, то однозначно стоило бы использовать 3 таска. А стоит ли применять подобную конструкцию из тасков для асинхронных методов?


Ответы (1 шт):

Автор решения: Alexander Petrov

Task.Run в данном случае совсем не нужен.

var usersTask = _db.Users.ToListAsync();
var infoTask = _client_api.GetAsync(request_to_additional_api);
var weatherTask = _client.GetAsync(request_to_weather_api);

var users = await usersTask;
var additionalInfo = await infoTask;

users.ForEach(u => u.AdditionalInfo = additionalInfo.Where(ai => ai.UserId == u.Id));

var weather = await weatherTask;

var resultDataViewModel = new ResultDataViewModel
{
    Users = users,
    Weather = weather
};

Запускаем три задачи без ожидания. Они все начинают выполняться, запросы уходят в БД и API.

В методе ForEach нужны значения двух завершённых задачи, поэтому перед вызовом этого метода ожидаем их.

Ожидание третьей задачи можно выполнить после ForEach. Таким образом, даже если она окажется долгой, то будет выполняться одновременно с ForEach.

→ Ссылка