【问题标题】:Using main form as Parent to a new form created on different thread使用主表单作为在不同线程上创建的新表单的父表单
【发布时间】:2012-01-11 14:17:57
【问题描述】:

我有一个运行 BackgroundWorker 线程的主窗体。 当工人运行时,我“冻结”主窗体并等待它完成,同时显示其进度。

在其中一个场景中,工作人员可以显示一个 OpenFileDialog 供用户选择文件。 我使用第三个线程来运行 OpenFileDialog 并将它的 ApartmentState 设置为 STA,因为 OpenFileDialog 需要它(如果我不这样做则抛出异常)并且工作人员 ApartmentState 是 MTA。

问题是我想将主窗体作为参数传递给 OpenFileDialog 线程,以便在调用 OpenFileDialog.ShowDialog 时可以使用它。 像这样的:

public void ThreadProcShowDialog(object param)
{
    Form parent = (Form)param;
    dialog.ShowDialog(parent);
}

当然,ShowDialog 会抛出:

跨线程操作无效:从 线程不是创建它的线程。

我怎样才能以线程安全的方式做到这一点?

这样做的目的是,OpenFileDialog 将在 STA 线程中运行,同时阻止主窗体在其上显示(阻止用户单击下面的窗体,从而隐藏 OpenFileDialog)。

谢谢

【问题讨论】:

    标签: backgroundworker openfiledialog sta mta


    【解决方案1】:

    找到了!

    与我一起工作的一位程序员同事提出了一个实际可行的简单解决方案。 而不是在第三个线程上运行 OpenFileDialog 只需在主窗体(启动工作线程的那个)上运行它。

    看起来像这样:

    //Code inside worker method
    OpenFileDialog dialog= new OpenFileDialog();
    DialogResult result = DialogResult.None;
    
    Invoke(new MethodInvoker(delegate() { result = dialog.ShowDialog(this); }));
    if (result == DialogResult.OK)
    {
        ...
    }
    

    这样我会阻止主窗体被点击,并且 OpenFileDialog 在 STA 线程中运行。

    并且认为解决它的人是 C++ 程序员。 ;-)

    我希望这对某人有所帮助......

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 2016-02-04
      相关资源
      最近更新 更多