【问题标题】:How to use async within a lambda which returns a collection如何在返回集合的 lambda 中使用异步
【发布时间】:2015-07-01 12:14:09
【问题描述】:

我有一个异步“上游”方法。我正在尝试遵循最佳实践,并在堆栈中全力以赴。

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

将控制器操作更改为异步似乎是可行的方法,但问题是异步方法在 lambda 中被多次调用。

如何等待返回多个结果的 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&lt;System.Threading.Tasks.Task&lt;ThingDetail&gt; 到目标类型System.Collections.Generic.IEnumerable&lt;ThingDetail&gt;

我哪里错了?

【问题讨论】:

  • 现在您选择返回带有任务的枚举,但是您尝试将其分配给带有 ThingDetail 的枚举,因为您可以使用 var 关键字直接声明类型,例如:var things=... 而不是 IEnumerable&lt;ThingDetail&gt; things = ...
  • result 未在代码块中定义。大概,你的意思是return Json(things, JsonRequestBehavior.AllowGet)

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


【解决方案1】:
  • 将您的Things 集合转换为Task&lt;Thing&gt;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&lt;Thing&gt;,因此约定是将Async 附加到其名称 - GetDetailAboutTheThingAsync

【讨论】:

  • “就是这样”。太好了,谢谢。我曾尝试过WhenAll 方法,但显然错过了一个中间步骤。我同意你关于异步方法命名约定的观点,我同意。我会实现这个。
  • 两个代码块的最后一行不应该是return Json(things, JsonRequestBehavior.AllowGet);吗? result 似乎没有在两个代码块中定义。
  • @M.Babcock 正确,现在已修复。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
  • 2016-11-25
  • 2020-01-24
  • 2018-02-14
  • 2021-11-17
相关资源
最近更新 更多