Когда я должен ждать своих асинков?
Мы в настоящее время реорганизуем разделы нашего проекта, чтобы асинхронно вверх и вниз, yay!
Из-за нашего различного понимания, я и его коллега (позвольте назвать его Джим), имеют разные мнения о том, как будет выполняться наш код async/await и какой способ его написать.
Вот пример метода Джим писал:
public async Task<HouseModel> GetHouseModel(Guid houseId)
{
House house = await _houseService.GetHouse(houseId);
Task<IEnumerable<Furniture>> furniture = _furnitureService.GetFurnitureForHouse(house);
Task<IEnumerable<Appliances>> appliances = _applianceService.GetAppliancesForHouse(house);
return _houseModelFactory.MakeHouseModel(await furniture, await appliances);
}
И пример того, как я буду писать:
public async Task<HouseModel> GetHouseModel(Guid houseId)
{
House house = await _houseService.GetHouse(houseId);
IEnumerable<Furniture> furniture = await _furnitureService.GetFurnitureForHouse(house);
IEnumerable<Appliances> appliances = await _applianceService.GetAppliancesForHouse(house);
return _houseModelFactory.MakeHouseModel(furniture, appliances);
}
Я понимаю: потому что методы как в furniture
и в appliance
описанном выше, требуют House
, они будут ждать, пока House
будет доступен, прежде чем продолжить. Затем оба метода, которые нуждаются в " House
будут выполняться, но второй метод (GetAppliancesForHouse
) не будет ждать завершения первого завершения перед запуском.
Джим понимает, что мы должны ждать обоих методов только тогда, когда они необходимы. Чтобы они оба работали параллельно друг другу. Он думает, что выполнение этого по-моему приведет к тому, что второй метод ждет первого, то есть: GetAppliancesForHouse
ждет GetFurnitureForHouse
.
Правильно ли какое-либо из этих понятий? Или мы просто собираемся, когда мы идем? Когда мы должны ждать?
Ответы
Ответ 1
Я понимаю: потому что методы как в мебели, так и в оборудовании, описанном выше, требуют House, они будут ждать, пока House будет доступен, прежде чем продолжить.
Ваше понимание неверно. Методы, требующие Хауса, они не ждут, когда вы получите Дом, потому что вам это нужно. Они не разрешают свои зависимости и когда ждать кода или нет самостоятельно. Код ждет, чтобы получить "Дома", потому что вы await
его. Он не осознает, что произойдет дальше.
Затем оба метода, которые нуждаются в "Хаусе", будут выполняться, но второй метод (GetAppliancesForHouse) не будет ждать завершения первого завершения перед запуском.
Аналогично, GetAppliancesForHouse
не будет иметь собственного понимания, если он должен ждать или не зависит от зависимостей. GetAppliancesForHouse
не будет запущен, потому что ваш код говорит перед тем, как ждать GetFurnitureForHouse
. Ваш код всегда будет работать последовательно.
Джим понимает, что мы должны ждать обоих методов только тогда, когда они необходимы. Чтобы они оба работали параллельно друг другу.
Это вообще правда. Как указывали другие, код все же может работать не параллельно, в зависимости от других факторов. Кроме того, могут быть законные причины не хотеть запускать код параллельно.
Он думает, что выполнение этого по-моему приведет к тому, что второй метод ждет первого, то есть: GetAppliancesForHouse ждет GetFurnitureForhouse.
Он прав.
Чтобы узнать, что именно происходит, вы можете установить точки останова и посмотреть, что происходит после каждой строки. В случае с Jims, после перехода от Furniture to Appliances, переменная мебели еще не имеет значения, она все еще является задачей, но вы уже находитесь в следующей строке.
В вашем случае, перейдя на строку "Техника", вы увидите, что мебель уже имеет значение, так как она ее ждала.
Ответ 2
Ни один из вас не прав, см. Ответ от @erndob по причинам. Однако на один из вопросов не ответил:
Когда мы должны ждать?
- Вы хотите, чтобы работа выполнялась последовательно? Используйте свой путь.
- Вы хотите, чтобы работа выполнялась параллельно? Используйте Джим.
Примечание. Джим-метод не будет выполняться параллельно, если используемый планировщик заданий не может одновременно запускать обе задачи, например, из-за нехватки системных ресурсов (спасибо @AdamSimon).