当需要保留某个执行顺序时,运行一堆异步任务

本文关键字:运行 任务 异步 一堆 保留 顺序 执行 | 更新日期: 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);