2011-06-01 131 views
1

我想打開一些非模型窗口(WPF),但是在這種情況下必須發生,我在非STA線程上。所以我開始一個新的線程並在那裏打開它們。但是一旦被打開,他們就會再次關閉。 (順便說一句,這些窗口的行爲應該獨立於主窗口,所以沒有所有者屬性設置)如何防止關閉新的STA線程上的非模態窗口關閉

private void SomeMethod_OnA_NON_STA_Thread() 
{ 
    // some other work here 

    Thread ANewThread = new Thread(OpenSomeWindows); 
    ANewThread.SetApartmentState(ApartmentState.STA); 
    ANewThread.Start(); 
} 


private void OpenSomeWindows() 
{ 
    TestWindow T; 

    for (int i = 0; i < 3; i++) 
    { 
     T = new TestWindow(); 
     T.Show(); 
    } 
} 

我在做什麼錯在這裏?

回答

3

如果你希望你的窗戶住,必須啓動消息循環您創建它們(否則你的線程只是退出,窗戶沒有機會使自己)後:

private void OpenSomeWindows() 
{ 
    for (int i = 0; i < 3; i++) 
    { 
     TestWindow T = new TestWindow(); 
     T.Show(); 
    } 
    Dispatcher.Run(); // <--------- 
} 

(在主線程的消息循環是由你的框架創建)

PS:我不知道該窗口是否可以被垃圾收集,所以我會繼續的地方引用它們:

List<TestWindow> windows = new List<TestWindow>(); 
for (int i = 0; i < 3; i++) 
{ 
    TestWindow t = new TestWindow(); 
    t.Show(); 
    windows.Add(t); 
} 
Dispatcher.Run(); 

P.P.S .:也許你想讓你的窗口在主線程中運行?其實你可以做到這一點。您只需要以下內容:

private void SomeMethod_OnA_NON_STA_Thread() 
{ 
    // some other work here 
    Application.Current.Dispatcher.Invoke(OpenSomeWindows); 
} 

private void OpenSomeWindows() 
{ 
    for (int i = 0; i < 3; i++) 
    { 
     TestWindow T = new TestWindow(); 
     T.Show(); 
    } 
    // this way, no Dispatcher.Run is needed 
} 
+0

Thx !!!!!現在它可以工作。再次,我發現我必須閱讀更多關於這個調度器的東西。 – 2011-06-01 15:39:16

+0

但是閱讀最後一次更新... – Vlad 2011-06-01 15:41:44

+1

這最後一次迭代:(Application.Current.Dispatcher.Invoke(OpenSomeWindows);)是(恕我直言)跨越不同線程處理UI的最佳方式,特別是如果你正在嘗試寫很快,並且不想學習或重新學習線程。我知道這很糟糕,但對於原型和小型項目,有時候你只是想要一些有用的東西,這就是事實。 – 2014-01-16 19:16:25

0

線程在調用方法結束時死亡。將ANewThread轉換爲字段(在類/表單級別聲明它)。