2

好的,我在这里有点困惑。SynchronzationContext浏览与DispatcherSynchronizationContext. 以下是 MSDN 杂志关于此类的摘录:

DispatcherSynchronizationContext (WindowsBase.dll: System.Windows.Threading) WPF 和 Silverlight 应用程序使用 DispatcherSynchronizationContext,它将委托以“正常”优先级排列到 UI 线程的 Dispatcher。当线程通过调用 Dispatcher.Run开始其 Dispatcher 循环时,此 SynchronizationContext 被安装为当前上下文。DispatcherSynchronizationContext 的上下文是单个 UI 线程。

排队到 DispatcherSynchronizationContext 的所有委托由特定的 UI 线程按照它们排队的顺序一次执行一个。当前实现为每个顶级窗口创建一个 DispatcherSynchronizationContext,即使它们都共享相同的底层 Dispatcher。

(从这里:https ://msdn.microsoft.com/magazine/gg598924.aspx )

让我感到困惑的是,我用粗体/斜体表示的两个部分似乎相互矛盾。第一个似乎DispatcherSynchronizationContext是每个线程创建一个并设置为线程的当前同步上下文。但是,第二个摘录说每个窗口DispatcherSynchronizationContext都创建一个,即使它们都共享相同的调度程序/UI 线程。

我错过了什么/不理解什么?

如果它真的是每个窗口一个,而不仅仅是每个线程,你如何获得DispatcherSynchronizationContext特定窗口的?

4

2 回答 2

1

在 WPF 中,SynchronizationContext本质上是 Dispatcher 的包装器。如果您查看这里的实现,您可以看到PostandSend方法包装了Invokeand BeginInvoke

文档所指的DispatcherSynchronizationContext是它正在抓取当前的 UI 线程来完成工作,即使用

Application.Current.Dispatcher

SyncrhonizationContext实际上是使用当前线程的调度程序,无论它是否与UI相关。

Thread.CurrentContext

由于所有 Windows 都在 UI 线程上运行,因此无法DispatcherSynchronizationContext为每个 Windows 获取特定的。

于 2016-04-25T17:56:11.270 回答
0

所有 UI 应用程序(如 WinForms 和 WPF)都有特殊的 UI 线程(用于当前窗口),并且 SynchronzationContext.Post(在 WPF 的情况下转换为 Dispatcher.BeginInvoke)将发送的委托作为参数设置到当前窗口的 UI 线程队列中。所以 - 每个窗口都有自己的 SynchronzationContext,但在线程中你可以使用不同的 SynchronzationContext。

还有一点 - 每个线程都有 ExecutionContext,但只有 UI 线程有 SynchronzationContext(在其他情况下 - 例如来自 CLR ThredPool - SynchronzationContext=null)。当您捕获上下文时:

ExecutionContext ec = ExecutionContext.Capture();

在 ExecutionContext 里面你会有 SynchronzationContext,所以

Thread.CurrentContext

这是关于 ExecutionContext , SynchronzationContext 你可以抓住

var sc = SynchronizationContext.Current; 
于 2016-06-04T14:23:14.027 回答