WPF - Dispatcher PushFrame()

Tri*_*ran 1 wpf multithreading dispatcher

我试图从几个不同的线程调用Dispatcher.PushFrame()但遇到错误:

必须在与DependencyObject相同的Thread上创建DependencySource.

这是一段代码:

_lockFrame = new DispatcherFrame(true);
Dispatcher.PushFrame(_lockFrame);
Run Code Online (Sandbox Code Playgroud)

当我尝试:

Dispatcher.CurrentDispatcher.Invoke(
    DispatcherPriority.Normal,
    new Action(() => _lockFrame = new DispatcherFrame(true));
Dispatcher.PushFrame(_lockFrame);
Run Code Online (Sandbox Code Playgroud)

我收到错误:

对象必须由同一个线程创建.

从不同的线程将多个帧推入Dispatcher的方法是什么?

Nir*_*Nir 15

在不同线程的同一个调度程序上调用PushFrame是没有意义的,你没有写出你想要解决的问题,但你的基于PushFrame的解决方案可能是错误的.

Dispatcher对象负责执行单个线程的代码和调度事件,每个线程都有一个由OS发送的消息队列,并包含鼠标点击之类的通知,调度程序有一个循环读取此队列并调用适当的事件.

有时您必须处理消息而不从方法返回到调度程序循环,这是一个很好的示例,它是响应用户输入的模态对话框(因此它们需要处理消息)而不会中断调用它们的方法的控制流.

这就是PushFrame的作用 - 它在代码中运行调度程序循环.

每个线程(可选)都有自己的消息队列,消息特定于属于该线程的窗口和控件,您无法从另一个线程处理线程的消息队列(Windows本身没有允许您使用的API)读另一个帖子的消息).

从另一个线程调用PushFrame是行不通的,因为你的调用发生在错误的线程上,PushFrame本身必须在调度程序管理的同一个线程上调用,你不能在另一个线程上调用它,因为它试图处理一个另一个线程上的线程消息.

使用Invoke或BeginInvoke在这里也没有意义,因为传递给那些方法的委托仅在调度程序处理消息时被调用,如果调度正在处理消息,则不需要调用PushFrame来使其处理消息.

如果你问另一个问题,描述你想要做什么,这里有人可能会帮助你,但从不同的线程调用Dispatcher.PushFrame永远不会起作用.

  • 谢谢,这是一个很好的解释!问题正如您所描述的那样.一个线程安全的模式对话框.那么基本上我如何使用一(1)个单模态对话框来处理来自多个线程的Show()请求? (2认同)