【发布时间】:2015-08-20 15:49:33
【问题描述】:
我正在尝试决定如何等待所有异步任务完成。
这是我目前拥有的代码
[HttpGet]
public async Task<JsonResult> doAsyncStuff()
{
var t1 = this.service1.task1();
var t2 = this.service2.task2();
var t3 = this.service3.task3();
var t4 = this.service4.task4();
await Task.WhenAll(t1,t2,t3,t4);
return this.Json(new {redirect = true, href = Url.Action("Blah")}, JsonRequestBehavior.AllowGet);
}
我很确定同步上下文不相关,所以我尝试了这个。
[HttpGet]
public async Task<JsonResult> doAsyncStuff()
{
var t1 = this.service1.task1().ConfigureAwait(false);
var t2 = this.service2.task2().ConfigureAwait(false);
var t3 = this.service3.task3().ConfigureAwait(false);
var t4 = this.service4.task4().ConfigureAwait(false);
await Task.WhenAll(t1,t2,t3,t4);
return this.Json(new {redirect = true, href = Url.Action("Blah")}, JsonRequestBehavior.AllowGet);
}
现在的问题是 Task.WhenAll 的参数无效,因为它不会接受已配置的任务 Awaiatables。
所以Task.WhenAll需要替换成这个
await t1; await t2; await t3; await t4;
这对我来说似乎不正确,但几乎任何人都对 ConfigureAwait 有什么要说的,它是“使用它,如果它没有出错”。据我所知(我没有编写任务),它们不使用同步上下文,也不依赖它。
需要注意的是,我希望 task1 到 task4 同时运行,因为它们不依赖于前一个完成。因此,我不想在每个任务前等待。但我不想在所有 4 个完成之前返回 Json 响应,这就是为什么我目前在当前代码中有 await Task.WhenAll()。
【问题讨论】:
-
我更新了您的标题,使其更能代表您遇到的实际问题和问题,如果您愿意,您可以将其改回,但“哪个更好”的问题不被接受,并且很可能在人们没有阅读您的实际问题的情况下引起下意识的反应。
-
这是“配置等待”,而不是“配置任务”。
-
@StephenCleary 当您在任务上使用 .ConfigureWait(false) 时,它会将任务变为已配置的任务等待对象。 msdn.microsoft.com/en-us/library/… 我的意思是 Task.WhenAll 不适用于所述对象。
-
@vipero07:对。我是说命名是正确使用的指示。
Task.WhenAll处理任务;它根本不使用await。 -
@StephenCleary 啊,我现在跟着。是的,好点。老实说,ConfigureAwait 是一种奇怪的名称,因为它读取 Configure Await false (比如......不要配置等待)。是的,我知道 false 是为了在捕获的上下文中继续,但它不是这样读的。
标签: c# asynchronous async-await