如果您只想并行执行这两个操作,那么您不需要async
- await
。您可以使用旧的 TPL 方法,例如Parallel.Invoke()
:
Parallel.ForEach(animals,
animal => {
Parallel.Invoke(
() => animal.Owner = GetAnimalOwner(ownerId),
() => animal.FavouriteFood = GetFavouriteFood(foodId));
Database.Store(animal);
});
请记住,不能保证这实际上会提高您的性能,具体取决于您的数据库和与它的连接。
一般来说,async
-await
在两种情况下有意义:
- 您想从 UI 线程中卸载一些长时间运行的代码。
- 您希望使用更少的线程来提高性能或可伸缩性。
在我看来,#1 不是你的情况。如果您是第 2 种情况,那么您应该将数据库方法重写为真正异步的方法(取决于您的数据库库,这可能是不可能的)。
如果你这样做,那么你可以做类似于 Scott Chamberlain 建议的事情(但不使用Parallel.ForEach()
):
var tasks = animals.Select(
async animal => {
var getOwnerTask = GetAnimalOwnerAsync(ownerId);
var getFavouriteFoodTask = GetFavouriteFoodAsync(foodId);
animal.Owner = await getOwnerTask;
animal.FavouriteFood = await getFavouriteFoodTask;
await Database.StoreAsync(animal);
});
await Task.WhenAll(tasks);
然后,这将以更大程度的并行性执行Parallel.ForEach()
(因为受线程池的限制),但同样,这实际上可能不会提高性能。如果您想限制并行度,您可以添加SemaphoreSlim
或改用 TPL Dataflow。