2017-02-03 94 views
0

在Windows表單應用程序使用對話框無論是主線應設置爲[STAThread]或單獨STA線程需要創建該對話框上運行。STA線程對話框

這裏談到的問題,我無法理解真的。一個已啓動的STA線程不會「有時」完成,所以主線程一直掛在Join()上。

現在我通過使用Application.DoEvents()而不是t.Join()來克服,現在看起來工作正常,但我仍然對「有時」取決於什麼感興趣。在例子中,我使用下面的靜態方法來打開一個openfile-/SAVEFILE對話框:

using System.Windows.Forms; 

namespace Dialog 
{ 
    public class clsDialogState 
    { 
     public DialogResult result; 
     public FileDialog dialog; 

     public void ThreadProcShowDialog() 
     { 
      result = DialogResult.None; 
      result = dialog.ShowDialog(); 
     }   
    } 

    public static class clsShowDialog 
    { 
     public static DialogResult STAShowDialog(FileDialog dialog) 
     { 
      clsDialogState state = new clsDialogState(); 
      state.dialog = dialog; 
      System.Threading.Thread t = new System.Threading.Thread(state.ThreadProcShowDialog); 
      t.SetApartmentState(System.Threading.ApartmentState.STA); 
      t.Start(); 
      //t.Join(); //Main thread might hang up here 
      while (state.result == DialogResult.None) Application.DoEvents(); //Everything is refreshed/repainted fine 
      return state.result; 
     } 
    } 
} 

所以用法是單純只是:

Dialog.clsShowDialog.STAShowDialog(new SaveFileDialog()); 
+0

晴UI組件(COM)是不是在所有的ThreaSafe並不會在MTA的環境中正常運行。 – codeteq

+0

在聲明線程STA你讓你不會阻止線程,一個承諾,你將有一個消息泵運行。如果你確實阻塞了一個STA線程或者沒有消息泵,隨機的壞事情可能會發生。有關更多詳細信息,請參見[此答案](http://stackoverflow.com/a/4530773/80274)。 –

+1

@ScottChamberlain確實,但'Thread.Join' *是一個抽水等待。如果調用者不是UI線程,我懷疑這會工作正常。 – Luaan

回答

1

我無法弄清楚到底是什麼讓調用線程掛當它正在等待一個STA線程完成時在join()上,但看起來它有時起作用,有時不起作用。最終,我決定通過使用:

while (InvokeResult == DialogResult.None) Application.DoEvents(); 

而不是Join()。