当需要保留某个执行顺序时,运行一堆异步任务
本文关键字:运行 任务 异步 一堆 保留 顺序 执行 | 更新日期: 2023-09-27 18:36:16
>我正在尝试异步我的原始代码
for(var item in items)
{
dbAccess.Save(item);
}
工作正常:
var tasks = new List<Task>();
for(var item in items)
{
tasks.Add(dbAccess.SaveAsync(item));
}
await Task.WhenAll(tasks);
但是,在将项目保存到数据库之前,我需要添加一个额外的清理调用:
var tasks = new List<Task>();
for(var item in items)
{
tasks.Add(dbAccess.DeleteAsync(item.id));
tasks.Add(dbAccess.SaveAsync(item));
}
await Task.WhenAll(tasks);
上面的代码不正确,因为在相应的 DeleteAsync 完成之前不应执行 SaveAsync。换句话说,删除必须始终位于每个项目的"保存"之前,但项目的顺序无关紧要。
有没有完美的方法可以做到这一点?
创建一个 async
方法,该方法对单个项目执行删除,然后保存,并对每个项目并行执行所有这些复合操作:
var tasks = items.Select(async item =>
{
await dbAccess.DeleteAsync(item.id);
await dbAccess.SaveAsync(item);
});
await Task.WhenAll(tasks);
您可以使用
Func<Task>
将两个异步调用封装到单个Task
中,如下所示:
for(var item in items)
{
//We store the value of item in a local variable
//because it is not recommended to close over a loop variable
var my_item = item;
Func<Task> task_fact = async () =>
{
await dbAccess.DeleteAsync(my_item.id);
await dbAccess.SaveAsync(my_item);
};
tasks.Add(task_fact());
}
这将创建一个 Task ,该任务调用 delete 方法,异步等待它,然后调用 save 方法并异步等待它。
您可以使用方法执行相同的操作。
如何使用 ContinueWith:
var tasks = new List<Task>();
for(var item in items)
{
var task = dbAccess.DeleteAsync(item.id)
.ContinueWith(antecedent => dbAccess.SaveAsync(item))
.Unwrap();
tasks.Add(task);
}
await Task.WhenAll(tasks);