初始化任务列表(对于 Task.WhenAll)以并行执行的正确方法是什么?



我一直在阅读并行执行任务的内容。我需要进行多个数据库行更新(每个都是独立的(。我想一次更新一行,而不是一次更新一行。请注意,在下面的代码中,dbConnection.ExecuteAsync返回一个Task<int>(即更新/删除的行的 #(。

以下是我目前的方法:

var deleteTasks = new List<Task<int>>();
foreach (var item in queries)
{
deleteTasks.Add(dbConnection.ExecuteAsync(item.RawSql, item.Parameters, transaction: transaction));
}
//ensure all queries are complete
await Task.WhenAll(deleteTasks);

现在上面的方法有效,但我也看到了以下两种方法:

var deleteTasksSelect1 = queries.Select(query => (dbConnection.ExecuteAsync(query.RawSql, query.Parameters, transaction: transaction)));
var deleteTasksSelect2 = queries.Select(async query => await (dbConnection.ExecuteAsync(query.RawSql, query.Parameters, transaction: transaction)));

他们俩都返回IEnumerable<Task<int>>.我试图了解我上面的方法与 LINQ 投影之间的区别。其中一个构建异步 Func,而另一个不,但都返回相同的结果。这些和正确的方法有什么区别?


请注意,为了获得我的结果(即受影响的行的 #,我在调用 Task.WhenAll(( 后执行以下操作:

var successCount = deleteTasks.Sum(x => x.Result)

我一直在阅读并行执行任务的内容。我需要进行多个数据库行更新(每个都是独立的(。我想一次更新一行,而不是一次更新一行。请注意,在下面的代码中,dbConnection.ExecuteAsync 返回一个任务(即更新/删除的行的 #(。

这将与帮助相反。如果您有一堆数据库操作,请不要针对数据库逐个发送它们。您必须传输的数据量是固定的,因此您所做的只是为它们中的每一个添加大量的网络连接和交易开销。这两个是您需要最小化的事情。该课程紧随"不要检索到您需要的更多数据,在 UI 中进行过滤"之后。

无论如何,表锁定可能不允许平行执行。很高兴您认为它们是独立的(可能是错误的(,DB不能那么确定。如果你发送一堆DML语句,它将为每个语句写锁定表(很可能还会阻止任何选择在它们上运行(。数据库就是将并发请求转换为一个很好的顺序操作。

如果你想学习无线程多任务处理,你需要一些与许多服务器交互的东西 - 而不仅仅是一个服务器。也许是"这个网站在线吗"之类的测试工具?

最新更新