等待异步代码似乎仍然是 运行 同步
await async code seems to still be running sync
我是 async / await 的新手,一直在尝试在我的 4.6 web api 2 项目中实现它。
public class MyController : ApiController
{
public async Task<Thing> Search(String searchTerms)
{
myThing = new Thing();
myThing.FirstProperty = await doFirstPropertyAsync(searchTerms);
myThing.SecondProperty = await doSecondPropertyAsync(searchTerms);
return myThing;
}
}
基本上我要返回一个 class (Thing),它有两个属性,每个属性都需要几秒钟来填充。我实际上正在加载大约 10 个属性,但所有属性的逻辑都是相同的。
public async Task<MyCoolSubObject> doFirstPropertyAsync(string searchTerms)
{
SomeController sController = new SomeController();
Debug.WriteLine("first - starting.");
var x = await Task.Run(()=>sController.Lookup(searchTerms));
Debug.WriteLine("first - finishing.");
return x;
}
public async Task<MyCoolSubObject> doSecondPropertyAsync(string searchTerms)
{
SomeOtherController sController = new SomeOtherController();
Debug.WriteLine("second - starting.");
var x = await Task.Run(()=>sController.Lookup(searchTerms));
Debug.WriteLine("second - finishing.");
return x;
}
我挠头的是什么:
当我查看调试输出时,第一个 属性 赋值方法调用在第二个完成之前开始并完成。再一次,我实际上有十个这样的东西,无论我把 属性 作业放在什么顺序,它们都会以连续的方式完成(即:在另一个完成之前什么都不会开始)。
这些 属性 幕后作业基本上是在进行需要一段时间的数据库调用,因此我希望它们 运行 如果可能的话并行进行。方法本身 ( SomeController.Lookup(string) ) 不包含 await/async/task 内容。
Again, I actually have like ten of these and no matter what order I
put the property assignments in they complete in a serial fashion (ie:
nothing starts until another one finishes).
发生这种情况是因为在您的代码中,您在启动任务后立即使用 await
关键字,这样做可以防止方法在任务完成之前继续执行下一条语句。
如果您想 运行 并行处理您的任务,您应该启动所有任务,然后才使用 Task.WhenAll
:
等待所有任务
public async Task<Thing> Search(String searchTerms)
{
myThing = new Thing();
var firstTask = doFirstPropertyAsync(searchTerms);
var secondTask = doSecondPropertyAsync(searchTerms);
await Task.WhenAll(firstTask, secondTask);
myThing.FirstProperty = await firstTask;
myThing.SecondProperty = await secondTask;
return myThing;
}
请注意,当我们在等待 Task.WhenAll 任务完成后分别等待每个任务时,我们这样做是为了从任务中获取结果,尽管我们可以使用结果 属性(它不会阻塞,因为我们知道任务已经完成)出于一致性原因,我更喜欢使用 await。
我是 async / await 的新手,一直在尝试在我的 4.6 web api 2 项目中实现它。
public class MyController : ApiController
{
public async Task<Thing> Search(String searchTerms)
{
myThing = new Thing();
myThing.FirstProperty = await doFirstPropertyAsync(searchTerms);
myThing.SecondProperty = await doSecondPropertyAsync(searchTerms);
return myThing;
}
}
基本上我要返回一个 class (Thing),它有两个属性,每个属性都需要几秒钟来填充。我实际上正在加载大约 10 个属性,但所有属性的逻辑都是相同的。
public async Task<MyCoolSubObject> doFirstPropertyAsync(string searchTerms)
{
SomeController sController = new SomeController();
Debug.WriteLine("first - starting.");
var x = await Task.Run(()=>sController.Lookup(searchTerms));
Debug.WriteLine("first - finishing.");
return x;
}
public async Task<MyCoolSubObject> doSecondPropertyAsync(string searchTerms)
{
SomeOtherController sController = new SomeOtherController();
Debug.WriteLine("second - starting.");
var x = await Task.Run(()=>sController.Lookup(searchTerms));
Debug.WriteLine("second - finishing.");
return x;
}
我挠头的是什么:
当我查看调试输出时,第一个 属性 赋值方法调用在第二个完成之前开始并完成。再一次,我实际上有十个这样的东西,无论我把 属性 作业放在什么顺序,它们都会以连续的方式完成(即:在另一个完成之前什么都不会开始)。
这些 属性 幕后作业基本上是在进行需要一段时间的数据库调用,因此我希望它们 运行 如果可能的话并行进行。方法本身 ( SomeController.Lookup(string) ) 不包含 await/async/task 内容。
Again, I actually have like ten of these and no matter what order I put the property assignments in they complete in a serial fashion (ie: nothing starts until another one finishes).
发生这种情况是因为在您的代码中,您在启动任务后立即使用 await
关键字,这样做可以防止方法在任务完成之前继续执行下一条语句。
如果您想 运行 并行处理您的任务,您应该启动所有任务,然后才使用 Task.WhenAll
:
public async Task<Thing> Search(String searchTerms)
{
myThing = new Thing();
var firstTask = doFirstPropertyAsync(searchTerms);
var secondTask = doSecondPropertyAsync(searchTerms);
await Task.WhenAll(firstTask, secondTask);
myThing.FirstProperty = await firstTask;
myThing.SecondProperty = await secondTask;
return myThing;
}
请注意,当我们在等待 Task.WhenAll 任务完成后分别等待每个任务时,我们这样做是为了从任务中获取结果,尽管我们可以使用结果 属性(它不会阻塞,因为我们知道任务已经完成)出于一致性原因,我更喜欢使用 await。