Dispatcher.RunAsync异步回调及UI任务等待在UWP与Unity中的线程差异问题
现象原因
这一差异本质是同步上下文(SynchronizationContext)的默认实现和捕获行为不同导致的:
- 原生UWP环境中,UI线程绑定的是
CoreDispatcherSynchronizationContext,默认情况下await操作会捕获当前的同步上下文,异步操作完成后的后续代码会被自动派发到原上下文(也就是UI线程)执行,因此Step2的Dispatcher.HasThreadAccess返回True。 - Unity运行时自己实现了独立的
UnitySynchronizationContext,和UWP原生的CoreDispatcher上下文不互通,且默认异步行为有两个特殊配置:- 未显式配置上下文捕获的情况下,
await的后续延续操作会默认被调度到线程池线程执行,等价于全局默认加了ConfigureAwait(false),不会切回原Dispatcher线程 - 你代码中用到的
Windows.UI.Core.CoreDispatcher是UWP原生的调度器,不属于Unity同步上下文的管理范围,await之后自然不会回到该Dispatcher绑定的STA线程
- 未显式配置上下文捕获的情况下,
兼容处理方案
如果要在Unity版本中保证两段代码都运行在符合要求的STA线程,可以用两种方案:
- 每次await完成后,手动将后续代码再次通过
Dispatcher.RunAsync派发到目标STA线程执行 - 所有需要保留上下文的await调用显式添加
ConfigureAwait(true),强制捕获当前调度上下文
内容的提问来源于stack exchange,提问作者Luz
相关产品推荐
相关产品推荐

