c# - task异步 - unity async await




我应该什么时候等待我的asyncs? (2)

我们目前正在重构我们项目的各个部分上下异步,是的!

由于我们的理解不同,我和同事(让我们称他为吉姆)对于我们的异步/等待代码将如何执行以及编写它的方式有不同的看法。

以下是Jim写的示例方法:

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

我的理解是:因为上述furnitureappliance服务的方法都要求House ,他们会等待House继续使用。 然后,两个需要House方法都会运行,但第二个方法( GetAppliancesForHouse )不会在开始之前等待第一个方法完成。

吉姆的理解是:我们应该只在需要时才等待这两种方法。 这样他们就会彼此平行。 他认为按照我的方式进行操作将导致第二种方法等待第一种方法,即: GetAppliancesForHouse等待GetFurnitureForHouse

这些理解中的任何一个是否正确? 或者我们一直在进行弥补? 我们何时应该等待?


我的理解是:因为上述家具和家电服务的方法都要求House,他们会等待House继续使用。

你的理解是错误的。 需要House的方法,他们不等你拿到House因为你需要它。 他们不解决他们的依赖关系以及何时等待代码或不自己。 代码等待获取Houses,因为您已经await 。 它不知道接下来会发生什么。

然后,两个需要House的方法都会运行,但第二个方法(GetAppliancesForHouse)不会在开始之前等待第一个方法完成。

类似地,如果GetAppliancesForHouse应该等待或不基于依赖GetAppliancesForHouse它将不会有自己的理解。 GetAppliancesForHouse将无法运行,因为您的代码首先要等待GetFurnitureForHouse您的代码将始终按顺序运行

吉姆的理解是:我们应该只在需要时才等待这两种方法。 这样他们就会彼此平行。

这通常是正确的。 正如其他人所指出的那样,代码仍然可能并不依赖于其他因素。 此外,可能有合理的理由不希望并行运行代码。

他认为按照我的方式进行操作将导致第二种方法等待第一种方法,即:GetAppliancesForHouse等待GetFurnitureForHouse。

他是对的。

要查看确切的结果,您可以放置​​断点并查看每行后发生的情况。 在Jims案例中,从家具到家用电器之后,家具变量还没有价值,它仍然是一项任务,但你已经在下一行了。

根据你的情况,去家电系列,你会看到家具已经有了价值,因为它等待它。


你们两个都不正确,请查看Erndob 的答案 。 但是,其中一个问题没有得到解答:

我们何时应该等待?

  • 你想要按顺序完成工作吗? 用你的方式。
  • 你想要并行完成工作吗? 用吉姆的方式。

注意 :如果使用的任务计划程序无法同时运行两个任务,例如由于缺少系统资源(感谢@AdamSimon ),Jim的方式实际上并不会并行运行。





async-await