异步调用完成后如何正确实现TaskDialogPage页面导航
问题根因
调用ConfigureAwait(false)后,await 后续代码会被调度到线程池线程执行,而TaskDialogPage.Navigate属于UI操作,必须在创建任务对话框的UI线程执行,且TaskDialogPage本身未继承Control类,无法直接调用Invoke方法。
方案1:使用BoundWindow的Invoke方法(最直接)
TaskDialogPage的BoundWindow属性返回承载当前对话框的窗口对象,该对象继承自Control,可直接用它的线程封送方法:
page.Created += async (_, _) => { await DoSomethingThatTakesTime().ConfigureAwait(false); page.BoundWindow.Invoke(() => page.Navigate(completedPage)); };
方案2:捕获UI同步上下文(通用方案)
提前捕获UI线程的同步上下文,异步操作完成后将导航操作投递到UI上下文执行:
page.Created += async (_, _) => { var uiContext = SynchronizationContext.Current; await DoSomethingThatTakesTime().ConfigureAwait(false); uiContext.Post(_ => page.Navigate(completedPage), null); };
方案3:省略ConfigureAwait(false)(最简方案)
如果没有特殊需求需要强制切换到线程池上下文,直接去掉ConfigureAwait(false)即可,await完成后会自动回到原始UI线程执行后续代码:
page.Created += async (_, _) => { await DoSomethingThatTakesTime(); page.Navigate(completedPage); };
注意:以上方案均默认在TaskDialogPage的Created事件中处理逻辑,此时BoundWindow已完成初始化,不会出现空引用异常。
内容的提问来源于stack exchange,提问作者Scover
相关产品推荐
相关产品推荐

