以下是您可能想要执行的操作:
public async Task<PewPew> SomeMethod(Foo foo)
{
// get the stuff on another thread
var cTask = Task.Run(() => GetAllTheCats(foo));
var fTask = Task.Run(() => GetAllTheFood(foo));
var cats = await cTask;
var food = await fTask;
return new PewPew
{
Cats = cats,
Food = food
};
}
public IList<Cat> GetAllTheCats(Foo foo)
{
// Do stuff, like hit the Db, spin around, dance, jump, etc...
// It all takes some time.
return cats;
}
public IList<Food> GetAllTheFood(Foo foo)
{
// Do more stuff, like hit the Db, nom nom noms...
// It all takes some time.
return food;
}
这里有两件事你需要理解:
-
这有什么区别:
var cats = 等待任务;
var food = 等待任务;
和这个:
Task.WaitAll(new [] {cTask, fTask});
两者都会给你类似的结果,在某种意义上让 2async
任务完成然后return new PewPew
- 然而,不同的是Task.WaitAll()
将阻塞当前线程(如果是 UI 线程,则 UI 将冻结)。反而,await
将分解SomeMethod
在状态机中说,然后从SomeMethod
当它遇到时给它的调用者await
关键词。它不会阻塞线程。下面的代码await
将计划在何时运行async
任务结束了。
-
你也可以这样做:
var cats = wait Task.Run(() => GetAllTheCats(foo));
var food = wait Task.Run(() => GetAllTheFood(foo));
然而,这不会启动async
同时执行任务。第一个任务结束后将开始第二个任务。这是因为如何await
关键字有效。
编辑:如何使用SomeMethod
- 在调用树开始的某个地方,你必须使用Wait()
or Result
财产 - 或者 - 你必须await
from async void
。
一般来说,async void
将是一个事件处理程序:
public async void OnSomeEvent(object sender, EventArgs ez)
{
Foo f = GetFoo();
PewPew p = await SomeMethod(f);
}
如果没有则使用Result
财产。
public Foo2 NonAsyncNonVoidMethod()
{
Foo f = GetFoo();
PewPew p = SomeMethod(f).Result; //But be aware that Result will block thread
return GetFoo2(p);
}