STA线程对话框

问题描述:

在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://*.com/a/4530773/80274)。 –

+1

@ScottChamberlain确实,但'Thread.Join' *是一个抽水等待。如果调用者不是UI线程,我怀疑这会工作正常。 – Luaan

我无法弄清楚到底是什么让调用线程挂当它正在等待一个STA线程完成时在join()上,但看起来它有时起作用,有时不起作用。最终,我决定通过使用:

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

而不是Join()。