0

我有一个运行 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)。

谢谢

4

1 回答 1

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++ 程序员。;-)

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

于 2012-01-11T06:17:57.160 回答