如何在返回集合的lambda中使用异步 [英] How to use async within a lambda which returns a collection

查看:115
本文介绍了如何在返回集合的lambda中使用异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个异步的上游"方法.我正在尝试遵循最佳做法,并在整个堆栈中一直保持全同步.

I have a method which is Async "upstream". I'm trying to follow best practice and go all-in qith async all the way up the stack.

如果我依靠.Result(),那么在MVC中的Controller动作中,我可以预料地遇到了死锁问题.

Within a Controller action within MVC I predictably hit the deadlock issue If I rely on .Result().

将Controller动作更改为异步似乎是一种方法,尽管问题是在lambda中多次调用了异步方法.

Changing the Controller action to async seems to be the way to go, though the issue is that the async method is called multiple times within a lambda.

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

How can I await on a lamda that returns multiple results?

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

}

您可以看到我已经尝试使lambda异步,但这只是给编译器一个例外:

You can see I have tried making the lambda async, but this just gives a compiler exception:

无法转换源类型

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

System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<ThingDetail> to target type System.Collections.Generic.IEnumerable<ThingDetail>

我在哪里错了?

推荐答案

  • 将您的Thing集合转换为Task<Thing>的集合.
  • 然后使用Task.WhenAll加入所有这些任务,然后等待它.
  • 等待联合任务将为您提供Thing[]
    • Convert your collection of Things into a collection of Task<Thing>s.
    • Then join all those tasks using Task.WhenAll and await it.
    • Awaiting the joint task will give you a 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);
      }
      

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

      Or, succinctly and using type inference:

      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.

      Note: since GetDetailAboutTheThing seems to return a Task<Thing>, the convention is to append Async to its name - GetDetailAboutTheThingAsync.

      这篇关于如何在返回集合的lambda中使用异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆