作用域与同步上下文(Synchronization Context)的关联及代码问题咨询
问题解答
作用域与同步上下文的关联
两者是完全不同维度的概念,没有绑定关系:
- 作用域是C#的编译期语法规则,用来限定变量、方法的可访问范围,比如方法内定义的局部变量,作用域就是整个方法的代码块,和代码最终运行在什么线程、什么上下文无关。
- 同步上下文是.NET的运行期调度机制,用来控制代码的执行线程和顺序,比如WPF的GUI线程自带专属的
DispatcherSynchronizationContext,保证UI操作只能在GUI线程执行,线程池线程则使用默认同步上下文。
给出的WPF代码运行失败的原因
不是同一作用域内跨同步上下文访问导致的,失败的核心原因有两个:
- WPF的GUI线程是单线程单元(STA)模型,
WaitHandle.WaitAll方法原生不支持在STA线程上调用,直接运行就会抛出NotSupportedException。 - 就算规避了上述API限制,
WaitHandle.WaitAll是阻塞调用,会直接卡住GUI线程。如果你的Indexer.WaitCallBack内部有任何需要调度回GUI线程执行的逻辑(比如更新UI控件、调用Dispatcher.Invoke等),就会直接触发死锁:工作线程等GUI线程处理调度任务,GUI线程卡在WaitAll上等工作线程发信号,两边都没法继续执行。
作用域是否可以跨越多个同步上下文
完全可以。
你给出的代码本身就是典型例子:局部变量doneEvents的作用域覆盖整个Search方法,它既被运行WPF同步上下文的GUI线程访问,也被你提交到线程池、运行默认同步上下文的WaitCallBack方法访问,语法层面完全允许,只需要你自行做好跨线程访问的线程安全控制即可。
内容的提问来源于stack exchange,提问作者Marcin
相关产品推荐
相关产品推荐

