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.
我有一个异步“上游”的方法。我正在尝试遵循最佳实践并在堆栈中一直进行qith异步。
Within a Controller action within MVC I predictably hit the deadlock issue If I rely on .Result().
在MVC中的Controller操作中,我可以预见到死锁问题如果我依赖.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.
将Controller操作更改为异步似乎是要走的路,尽管问题是在lambda中多次调用async方法。
How can I await on a lamda that returns multiple results?
我如何等待返回多个结果的lamda?
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:
您可以看到我尝试使lambda异步,但这只是一个编译器异常:
Cannot convert source type
无法转换源类型
System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<ThingDetail>
to target typeSystem.Collections.Generic.IEnumerable<ThingDetail>
System.Collections.Generic.IEnumerable
到目标类型System.Collections.Generic.IEnumerable
Where am I going wrong here?
我在哪里错了?
1 个解决方案
#1
15
- Convert your collection of
Thing
s into a collection ofTask<Thing>
s. -
将您的Things集合转换为Task
的集合。 - Then join all those tasks using
Task.WhenAll
and await it. - 然后使用Task.WhenAll加入所有这些任务并等待它。
- 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);
}
Fiddle: https://dotnetfiddle.net/78ApTI
小提琴:https://dotnetfiddle.net/78ApTI
Note: since GetDetailAboutTheThing
seems to return a Task<Thing>
, the convention is to append Async
to its name - GetDetailAboutTheThingAsync
.
注意:由于GetDetailAboutTheThing似乎返回Task
#1
15
- Convert your collection of
Thing
s into a collection ofTask<Thing>
s. -
将您的Things集合转换为Task
的集合。 - Then join all those tasks using
Task.WhenAll
and await it. - 然后使用Task.WhenAll加入所有这些任务并等待它。
- 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);
}
Fiddle: https://dotnetfiddle.net/78ApTI
小提琴:https://dotnetfiddle.net/78ApTI
Note: since GetDetailAboutTheThing
seems to return a Task<Thing>
, the convention is to append Async
to its name - GetDetailAboutTheThingAsync
.
注意:由于GetDetailAboutTheThing似乎返回Task