如何在新线程上打开窗口? [英] How do I open a window on a new thread?

查看:148
本文介绍了如何在新线程上打开窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个选项窗口和一个根据这些选项和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆