如何解决异步等待过度使用
我有一个关于过度使用 async-await
运算符的问题。
我有一个 Zoo
实例列表,我需要将每个 Zoo
的每个成员分别插入到数据库中。这是 Zoo
类定义:
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
运算符在完成之前都会释放线程,但方法是在并行任务中调用的,因此线程用于不同的任务。也许从 async-await
lambda 中移除一些 Task.Run
更容易接受?
解决方法
这不是 await
过度使用的情况,而是 await
滥用的情况。 Parallel.ForEach
方法 is not async-friendly 和一个 async
委托是一个错误:它没有做你期望它做的事情。如果要同时启动多个异步操作,同时控制并发级别,则正确使用的 API 是 Parallel.ForEachAsync
方法。此方法将在即将推出的 .NET 6 中引入,因此目前您只能使用自制解决方案,例如在 this 问题中找到的解决方案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。