簡體   English   中英

如何在新線程上打開窗口?

[英]How do I open a window on a new thread?

我有一個選項窗口和一個窗口,根據這些選項和Kinect數據顯示顏色。 到目前為止,一切都在一個線程上(據我所知;我沒有做任何線程)。

現在,我正在添加一個選項來打開一個需要以盡可能低的延遲進行更新的查看器窗口。 所有這一切都需要創建一個窗口並顯示它:

viewer = new SkeletalViewer.MainWindow();
viewer.Show();

當此事件觸發時,顏色窗口停止顯示顏色(即主線程上每秒觸發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();

    }

無論我是否如上所述調用viewer.Show()或Invoke(),該行都會拋出異常: 不能使用屬於與其父Freezable不同的線程的DependencyObject。 這是我理解Invoke()的方式:它訪問查看器的調度程序,它知道運行該對象的線程,然后可以從該線程調用方法。

我應該嘗試將此查看器放在新線程上嗎? 問題甚至是線程問題嗎? 用戶不會與觀看者交互。

任何人都知道為什么這不起作用? 謝謝您的幫助。

您需要在創建窗口的同一個線程上調用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();
}

請參閱多個Windows /多個線程示例: http//msdn.microsoft.com/en-us/library/ms741870.aspx

所以我遇到了一個類似的問題,一個新窗口無法在新線程上打開。 例外是“不能使用屬於不同線程的dependencyobject”。

問題最終是窗口使用全局資源(背景畫筆)。 一旦我凍結了畫筆資源,窗口加載就好了。

我不確定這是否會解決您的問題,但您可以嘗試創建一個線程proc(打開一個查看器窗口),它在另一個線程上執行,然后有一個dispatcher.beginInvoke來更新主窗口,

這是一些代碼 -

    in the constructor register this
    public MainWindow()
    { 
       UpdateColorDelegate += UpdateColorMethod;
    } 

    // delegate and event to update color on mainwindow 
    public delegate void UpdateColorDelegate(string colorname);
    public event UpdateColorDelegate updateMainWindow;

    // launches a thread to show viewer
    private void launchViewerThread_Click(object sender, RoutedEventArgs e)
    {
        Thread t = new Thread(this.ThreadProc);
        t.Start();
    }

    // thread proc
    public void ThreadProc()
    {
       // code for viewer window
       ...
       // if you want to access any main window elements then just call DispatchToMainThread method
       DispatchToUiThread(color);   
    } 

    // 
    private void DispatchToUiThread(string color)
    {
      if (updateMainWindow != null)
      {
        object[] param = new object[1] { color};
        Dispatcher.BeginInvoke(updateMainWindow, param);
      }
    }

    // update the mainwindow control's from this method
    private void UpdateColorMethod(string colorName)
    {
       // change control or do whatever with main window controls
    } 

有了它,您可以更新主窗口控件而不凍結它,如果您有任何疑問,請告訴我

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM