使用main form作为Parent在不同线程上创建的新表单

时间:2012-01-10 09:22:28

标签: backgroundworker openfiledialog sta mta

我有一个运行BackgroundWorker线程的主窗体。 当工人正在跑步的时候我会冻结"主要形式并等待它完成,同时显示其进展。

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

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

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

当然,ShowDialog抛出:

  

跨线程操作无效:控制'表格'从a访问   除了创建它的线程以外的线程。

如何以线程安全的方式执行此操作?

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

由于

1 个答案:

答案 0 :(得分:2)

发现它!

与我一起工作的同事程序员提出了一个实际有效的简单解决方案。 而不是在第三个线程上运行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 ++程序员。 ; - )

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