异步等待过度使用

Async-await overuse

我有一个关于过度使用 async-await 运算符的问题。
我有一个 Zoo 实例列表,我需要将每个 Zoo 的每个成员分别插入到数据库中。这是 Zoo class 定义:

class Zoo
{
public Dog Dog { get; set; }
public Cat Cat { get; set; }
public Bear Bear { get; set; }
}

下面提供了插入Zoo的方法。 Zoo 的每个实例及其成员都应在插入前进行验证或转换,因此我用 Parallel.For:

来处理它们
public void Save(List<Zoo> zoos)
{
 Parallel.For(0, zoos.Count, new ParallelOptions { MaxDegreeOfParallelism = 4 }, async i =>
  {
  ...
  Task saveDog = Task.Run(async () => await InsertDogAsync(zoos[i], string connectionString));
  Task saveCat = Task.Run(async () => await InsertCatAsync(zoos[i], string connectionString));
  Task saveBear = Task.Run(async () => await InsertBearAsync(zoos[i], string connectionString));
  await Task.WhenAll(new Task[] { saveDog, saveCat, saveBear });
  ...
  });
}

我使用 async 方法将动物插入数据库。例如这里是 Dog:

private static async Task InsertDogAsync(Zoo zoo, string connectionString)
{
 using SqlConnection connection = new SqlConnection(connectionString);
 await connection.OpenAsync();
 ...
 using SqlCommand insertCommand = new SqlCommand("sp_insertDog", connection); // stored procedure
 ...
 await insertCommand.ExecuteNonQueryAsync();
}

我的问题如下: async-await 运算符是否过度使用?正如我所意识到的,每个 await 运算符在完成之前释放线程,但是在并行任务中调用方法,因此线程用于不同的任务。也许从 Task.Run lambda?

中删除一些 async-await 更容易接受

这不是 await 过度使用,而是 await 滥用。 Parallel.ForEach method is not async-friendly, and feeding it with an async delegate is a bug: it doesn't do what you expect it to do. If you want to launch multiple asynchronous operation concurrently, while keeping the level of concurrency under control, the correct API to use is the Parallel.ForEachAsync method. This method will be introduced with the upcoming .NET 6, so for now you can utilize only home-made solutions, like the ones found in this 问题。