子列表上的任务/异步Lambda将调用另一个方法

时间:2017-01-24 17:04:40

标签: c# asynchronous lambda async-await

我要求我替换作为另一个列表(StatusName中的字段的列表中的字段(ChildItems)的值(ParentItems)。我没有使用Async / Await做很多工作,所以我确定我没有正确地做到这一点

以下是我尝试的例子:

public class parentItem {
    public int Id {get;set;}
    public string Name {get;set;}
    public string Description {get;set;}
    public List<childItem> ChildItems {get;set;}
}

public class childItem {
    public int Id {get;set;}
    public string Name {get;set;}
    public string StatusId {get;set;}
    public string StatusName {get;set;}
}

// Populate parent in list.
List<parentItem> parents = new List<parentItem>();
//populate....

我们有一个数据调用,它将在异步await方法中填充这些元素。我希望做一个简单的lambda表达式,它将调用另一个方法来改变状态值

有点像这样:

// lambda I was hoping to try
parents = parents.Select((par) => {
   par.ChildItems = par.ChildItems.Select((sub) => {
      sub.StatusName = await ChangeChildStatusName(sub.StatusId);
   }).ToList();
   return par;
});

public async Task<string> ChangeChildStatusName(int statusId) {
    // code.
}

在此方法(ChangeChildStatusName)中,有一个数据库调用获取所需的其他信息。我很确定这种方法有不同的方法,但到目前为止我还没有找到适合这种情况的解决方案。

1 个答案:

答案 0 :(得分:0)

这里的关键是要注意你的类型。内部Select(添加return sub;之后)的结果是List<Task<childItem>>,您可以使用await Task.WhenAll(..)(异步)等待它们全部完成。同样,您的父任务可以使用相同的技术:

var parentTasks = parents.Select(async (par) => {
 var childTasks = par.ChildItems.Select(async (sub) => {
   sub.StatusName = await ChangeChildStatusName(sub.StatusId);
   return sub;
 });
 par.ChildItems = (await Task.WhenAll(childTasks)).ToList();
 return par;
});
parents = (await Task.WhenAll(parentTasks)).ToList();

但是,在您的特定情况下(访问数据库),您可能一次只能进行一次数据库调用,因此您应该用嵌套的Select替换嵌套的foreach:< / p>

foreach (var par in parents)
  foreach (var sub in par.ChildItems)
    sub.StatusName = await ChangeChildStatusName(sub.StatusId);