我们当前正在重构项目的各个部分,以便上下同步,是的!
由于我们的理解不同,我和一位同事(我们叫他吉姆)对我们的异步/等待代码将如何执行以及编写方式有不同的看法。
这是吉姆写的示例方法:
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
)不会等待第一个方法完成才开始。
Jim的理解是:只有在需要这两种方法时,我们才应该等待它们。这样它们将彼此平行运行。他认为,以我的方式进行操作将导致第二种方法等待第一种方法,即:GetAppliancesForHouse
等待GetFurnitureForHouse
。
这些理解是否正确?还是我们一直在进行弥补?我们什么时候应该等待?
答案 0 :(得分:49)
我的理解是:由于上述家具和家电服务中的方法都需要House,因此他们将等待House可用后再继续。
您的理解是错误的。需要众议院的方法,他们不是在等待您获得众议院,因为您需要它。他们不解决自己的依赖关系以及何时等待代码或不等待代码。 代码等待获得房屋,因为您之前有await
。它不知道接下来会发生什么。
然后,需要House的两个方法都将运行,但是第二个方法(GetAppliancesForHouse)将在启动之前不等待第一个方法完成。
类似地,GetAppliancesForHouse
对于是否应该依赖于依赖项也不会有自己的了解。 GetAppliancesForHouse
无法运行,因为您的代码要求先等待GetFurnitureForHouse
。 您的代码将始终按顺序运行。
Jim的理解是:只有在需要这两种方法时,我们才应该等待它们。这样它们将彼此平行运行。
通常是这样。正如其他人指出的那样,取决于其他因素,该代码可能仍不能并行运行。另外,可能有正当的理由不想并行运行代码。
他认为按照我的方式进行操作会导致第二种方法等待第一种方法,即:GetAppliancesForHouse等待GetFurnitureForHouse。
他是对的。
要查看确切发生了什么,可以放置断点并查看每行之后发生的情况。 在吉姆斯的情况下,从“家具”到“家电”之后,家具变量尚无价值,这仍然是一项任务,但是您已经在下一行了。
在您的案例中,转到“设备”行,您将看到家具已经具有该值,因为它在等待它。
答案 1 :(得分:8)
你们俩都不正确,请参阅the answer的@erndob,以了解原因。但是,未回答其中一个问题:
我们什么时候应该等待?
注意:如果使用的任务计划程序无法同时运行两个任务,例如,由于缺少系统资源,Jim的方法实际上不会并行运行(感谢{{3 }}。