【问题标题】:STA thread for dialog boxes用于对话框的 STA 线程
【发布时间】: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


【解决方案1】:

当调用线程等待 STA 线程完成时,我无法弄清楚是什么导致调用线程挂在 join() 上,但看起来它有时有效,有时无效。最后我决定通过使用来克服:

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

而不是 Join()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多