我是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;
}
}
基本上我正在返回一个类(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东西。
答案 0 :(得分:1)
同样,我实际上有十个这样的,不管我是什么顺序 将属性分配以连续方式完成(即: 没有什么可以开始,直到另一个完成。)
这是因为在您的代码中,一旦启动任务就会使用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任务已经完成后,我们单独等待每个任务时,我们这样做是为了从任务中获取结果,尽管我们可以使用Result属性(它不会阻止,因为我们知道任务已经完成了)我更倾向于使用await来保持一致性。