如何在新线程上打开窗口?

mic*_*ald 10 c# multithreading invoke

我有一个选项窗口和一个窗口,根据这些选项和Kinect数据显示颜色.到目前为止,一切都在一个线程上(据我所知;我没有做任何线程).

现在,我正在添加一个选项来打开一个需要以尽可能低的延迟进行更新的查看器窗口.所有这一切都需要创建一个窗口并显示它:

viewer = new SkeletalViewer.MainWindow();
viewer.Show();
Run Code Online (Sandbox Code Playgroud)

当此事件触发时,颜色窗口停止显示颜色(即主线程上每秒触发30次的事件停止触发),但查看器显示完美.我希望更新查看器和颜色窗口.

从阅读其他问题,听起来解决方案是在新线程上创建查看器.不过,我遇到了很多问题.

单击按钮打开查看器时会触发:

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();

    }
Run Code Online (Sandbox Code Playgroud)

无论我是否如上所述调用viewer.Show()或Invoke(),该行都会抛出异常:不能使用属于与其父Freezable不同的线程的DependencyObject.这是我理解Invoke()的方式:它访问查看器的调度程序,它知道运行该对象的线程,然后可以从该线程调用方法.

我应该尝试将此查看器放在新线程上吗?问题甚至是线程问题吗?用户不会与观看者交互.

任何人都知道为什么这不起作用?谢谢您的帮助.

shf*_*301 18

您需要调用Show()创建窗口的相同线程 - 这就是您收到错误的原因.然后,您还需要启动一个新的Dispatcher实例来获取运行时来管理窗口.

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();
}
Run Code Online (Sandbox Code Playgroud)

请参阅多个Windows /多个线程示例:http://msdn.microsoft.com/en-us/library/ms741870.aspx