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.
Within a Controller action within MVC I predictably hit the deadlock issue If I rely on .Result().
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.
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);
}
You can see I have tried making the lambda async, but this just gives a compiler exception:
Cannot convert source type
System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<ThingDetail>to target typeSystem.Collections.Generic.IEnumerable<ThingDetail>
Where am I going wrong here?
Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.
Async Method Return Types There are three return types that a method marked async may have: void. Task. Task< T > for some type T.
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.
Things into a collection of Task<Thing>s.Task.WhenAll and await it.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); }   Fiddle: https://dotnetfiddle.net/78ApTI
Note: since GetDetailAboutTheThing seems to return a Task<Thing>, the convention is to append Async to its name - GetDetailAboutTheThingAsync.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With