【发布时间】:2017-02-03 16:13:24
【问题描述】:
要在 Windows 窗体应用程序中使用对话框,应将主线程设置为 [STAThread],或者需要创建单独的 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());
【问题讨论】:
-
大多数 UI 组件 (COM) 根本不是 ThraSafe,并且无法在 MTA 环境中正常运行。
-
当您声明一个线程 STA 时,您承诺不会阻塞该线程并且您将运行一个消息泵。如果您确实阻止了 STA 线程或没有消息泵,则可能会发生随机的坏事。有关更多详细信息,请参阅this answer。
-
@ScottChamberlain 没错,但
Thread.Join是等待。我怀疑如果调用者不是 UI 线程,这会正常工作。
标签: c# .net openfiledialog savefiledialog sta