如何在新线程上打开窗口? [英] How do I open a window on a new thread?
问题描述
我有一个选项窗口和一个根据这些选项和Kinect数据显示颜色的窗口.到目前为止,所有内容都在一个线程上(据我所知;我还没有执行任何线程处理).
I have a options window and a window that displays color based on these options and Kinect data. So far everything's on one thread (as far as I know; I haven't done any threading).
现在,我添加了一个选项来打开查看器窗口,该窗口需要以尽可能短的延迟进行更新.所有这些需要创建一个窗口并显示它:
Now, I'm adding an option to open a viewer window that will need to be updated with lowest possible latency. All this entails is creating a window and showing it:
viewer = new SkeletalViewer.MainWindow();
viewer.Show();
当该事件触发时,颜色窗口停止显示颜色(即,在主线程上每秒触发30次的事件停止触发),但查看器显示完美.我希望查看器和颜色窗口都被更新.
When this event fires, the color window stops displaying colors (i.e. the event that fires 30 times a second on the main thread stops firing), but the viewer is displayed perfectly. I want the viewer and the color window to both be updated.
通过阅读其他问题,听起来解决方案是在新线程上创建查看器.不过,我遇到了很多问题.
From reading other questions, it sounds like the solution is to create the viewer on a new thread. I'm encountering a lot of problems with this, though.
点击按钮打开查看器时会触发:
This fires when I click the button to open the viewer:
private void launchViewerThread_Click(object sender, RoutedEventArgs e)
{
Thread viewerThread = new Thread(delegate()
{
viewer = new SkeletalViewer.MainWindow();
viewer.Dispatcher.Invoke(new Action(delegate()
{
viewer.Show();
}));
});
viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception
viewerThread.Start();
}
无论我是如上所述只是调用viewer.Show()还是Invoke(),该行都会引发异常:不能使用与其父级Freezable属于不同线程的DependencyObject.这就是我对Invoke()的理解:它访问查看器的调度程序,该调度程序知道对象在哪个线程上运行,然后可以从该线程中调用方法.
Regardless of if I just call viewer.Show() or Invoke() it as above, the line throws an exception: Cannot use a DependencyObject that belongs to a different thread than its parent Freezable. Here's how I understand Invoke(): it accesses viewer's dispatcher, which knows what thread the object is running on, and can then call methods from that thread.
我应该尝试将此查看器放在新线程上吗?问题甚至是线程问题吗?用户将不会与查看器进行交互.
Should I be trying to put this viewer on a new thread? Is the problem even a question of threads? The user will not be interacting with the viewer.
有人知道为什么这行不通吗?感谢您的帮助.
Anyone know why this doesn't work? Thanks for the help.
推荐答案
您需要在创建窗口的同一线程上调用Show()
-这就是为什么您会收到错误消息.然后,您还需要启动一个新的Dispatcher实例以获取运行时来管理窗口.
You need to call Show()
on the same thread that the window is created on - that's why you are getting the error. Then you also need to start a new Dispatcher instance to get the runtime to manage the window.
private void launchViewerThread_Click(object sender, RoutedEventArgs e)
{
Thread viewerThread = new Thread(delegate()
{
viewer = new SkeletalViewer.MainWindow();
viewer.Show();
System.Windows.Threading.Dispatcher.Run();
});
viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception
viewerThread.Start();
}
请参见位于以下位置的多个Windows/多个线程"示例: http://msdn. microsoft.com/en-us/library/ms741870.aspx
See the Multiple Windows/Multiple Threads example at: http://msdn.microsoft.com/en-us/library/ms741870.aspx
这篇关于如何在新线程上打开窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!