如何在lambda中使用async,返回集合

时间:2015-04-23 10:50:57

标签: c# asp.net-mvc linq asynchronous lambda

我有一个异步“上游”的方法。我正在尝试遵循最佳实践并在堆栈中一直进行qith异步。

在MVC中的Controller操作中,我可以预见到死锁问题如果我依赖.Result()。

将Controller操作更改为async似乎是要走的路,尽管问题是在lambda中多次调用async方法。

如何等待返回多个结果的lamda

public async Task<JsonResult>  GetLotsOfStuff()
{
    IEnumerable<ThingDetail> things=  previouslyInitialisedCollection
                                      .Select(async q => await GetDetailAboutTheThing(q.Id)));
    return Json(result, JsonRequestBehavior.AllowGet);

}

你可以看到我尝试使lambda异步,但这只是一个编译器异常:

无法转换来源类型

  
    

System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<ThingDetail>定位类型System.Collections.Generic.IEnumerable<ThingDetail>

  

我在哪里错了?

1 个答案:

答案 0 :(得分:15)

  • 将您的Thing集合转换为Task<Thing> s。
  • 的集合
  • 然后使用Task.WhenAll加入所有这些任务并等待它。
  • 等待联合任务会给你一个Thing[]


public async Task<JsonResult>  GetLotsOfStuff()
{
    IEnumerable<Task<ThingDetail>> tasks = collection.Select(q => GetDetailAboutTheThing(q.Id));

    Task<int[]> jointTask = Task.WhenAll(tasks);

    IEnumerable<ThingDetail> things = await jointTask;

    return Json(things, JsonRequestBehavior.AllowGet);
}

或者,简洁地使用类型推断:

public async Task<JsonResult>  GetLotsOfStuff()
{
    var tasks = collection.Select(q => GetDetailAboutTheThing(q.Id));
    var things = await Task.WhenAll(tasks);

    return Json(things, JsonRequestBehavior.AllowGet);
}

小提琴:https://dotnetfiddle.net/78ApTI

注意:由于GetDetailAboutTheThing似乎返回Task<Thing>,因此惯例是将Async附加到其名称 - GetDetailAboutTheThingAsync