我正在制作Windows 8.1平板电脑应用,并且大量使用async关键字。
我对async关键字的理解是,尽管它对程序员来说似乎是同步的,但不能保证在等待结束时将在同一线程上运行。
在文件后面的代码中,我使用了Dispatcher来在UI线程上运行任何UI更新。我发现的每个示例都表明在使用“回调”类型方案时,这是一种很好的做法,但是在使用异步方法时,我没有提到它。从我对异步的理解来看,似乎在每次等待调用后只要要更新UI时都需要使用调度程序。
通过将我的理解放在下面的代码中,我试图变得更加清晰。
private void SomeEventHandler(object sender, RoutedEventArgs e)
{
UpdateUI(); //This should run in my UI thread
await Foo(); //When Foo returns I have no guarantee that I am in the same thread
UpdateUI(); //This could potentially give me an error
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
UpdateUI(); //This will run in the UI thread
});
}
我是否只需要访问UIContext,线程就没有关系了?如果有人可以为我澄清这一点,那就太好了。
最佳答案
不完全正确...如果启动异步操作的线程具有同步上下文(对于UI线程而言是正确的),则将始终在同一线程上继续执行,除非您明确指定不使用.ConfigureAwait(false)
捕获同步上下文。
如果没有同步上下文,或者没有捕获它,那么将在ThreadPool
线程上继续执行(除非等待的任务实际上是同步完成的,在这种情况下,您将停留在同一线程上)。
因此,这是带有更新注释的代码段:
private void SomeEventHandler(object sender, RoutedEventArgs e)
{
UpdateUI(); //This should run in my UI thread
await Foo(); //When Foo returns I am still in the UI thread
UpdateUI(); //This will work fine, as I'm still in the UI thread
// This is useless, since I'm already in the UI thread ;-)
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
UpdateUI(); //This will run in the UI thread
});
}