我在一个新线程中打开一个新的WPF窗口,如下所示:
private void OnCreateNewWindow(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
Window1 w = new Window1();
w.Show();
Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
}
问题是它被困在Show方法上(没有显示窗口),并且永远不会到达Dispatcher.Run.
当检查线程和调用堆栈时,我可以看到两个线程,Main和我的新窗口线程。窗口线程的调用堆栈位于以下帧:
PresentationCore.dll!System.Windows.Input.CommandManager.FindCommandBinding(对象发送方,System.Windows.RoutedEventArgs e,System.Windows.Input.ICommand命令,布尔执行)+0x1c0字节
当尝试修改代码时,我曾经设法得到一个异常消息:
不能使用属于以下线程的DependencyObject其父级Freezable。
我有一种感觉,这与访问未冻结的主线程所拥有的资源有关。在这个应用程序中,我有很多通用的样式和资源,画笔等,但我试图通过在窗口的构造函数中放入以下内容来避免在这个特定的对话框中使用它们:
InheritanceBehavior=继承行为SkipAllNow;
但这似乎还不够。不知怎么的,一些未允许的资源似乎无论如何都被访问了。
带有FindCommandBinding的帧暗示它可能是命令绑定的问题。但此对话框没有命令绑定。
如果资源是在资源字典中定义的,那么像画笔这样的资源是否被隐式冻结了?如果没有,如何以简单的方式明确地冻结它们?有数百把刷子。但这可能不是问题所在。
还有其他想法吗?
您需要使用Dispatcher.Invoke或BegingInvoke方法来执行winodw对象的创建和调用show方法。工作线程无法调用或更新控件。
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, () => new Thread(() => { Window1 w = new Window1(); w.Show();})