使用主窗体作为在不同线程上创建的新窗体的父窗体
我有一个运行BackgroundWorker 线程的主窗体。 当工作人员运行时,我“冻结”主窗体并等待它完成,同时显示其进度。
在其中一种场景中,工作人员可以显示 OpenFileDialog 供用户选择文件。 我使用第三个线程来运行 OpenFileDialog 并将其 ApartmentState 设置为 STA,因为 OpenFileDialog 需要它(如果我不这样做,则会引发异常)并且工作器 ApartmentState 是 MTA。
问题是我想将主窗体作为参数传递给 OpenFileDialog 线程,以便在调用 OpenFileDialog.ShowDialog 时可以使用它。 像这样:
public void ThreadProcShowDialog(object param)
{
Form parent = (Form)param;
dialog.ShowDialog(parent);
}
当然,ShowDialog 会抛出:
跨线程操作无效:从 a 访问控制“表单” 除了创建它的线程之外的线程。
我怎样才能以线程安全的方式做到这一点?
这样做的目的是 OpenFileDialog 将在 STA 线程中运行,同时阻止主窗体在其上显示(阻止用户单击下面的窗体,从而隐藏 OpenFileDialog)。
谢谢
I have a main form that runs a BackgroundWorker thread.
While the worker is running I "freeze" the main form and wait for it to finish while showing its progress.
In one on the scenarios the worker can display an OpenFileDialog for the user to select a file.
I use a third thread to run the OpenFileDialog and set it's ApartmentState to STA because the OpenFileDialog demands it (throws exception if I don't do it) and the worker ApartmentState is MTA.
The problem is that I want to pass to the OpenFileDialog thread the main form as a parameter so it can be used when calling OpenFileDialog.ShowDialog.
Something like this:
public void ThreadProcShowDialog(object param)
{
Form parent = (Form)param;
dialog.ShowDialog(parent);
}
Of course, ShowDialog throws:
Cross-thread operation not valid: Control 'Form' accessed from a
thread other than the thread it was created on.
How can I do this in a thread safe manner?
The object of this is that the OpenFileDialog will run in a STA thread while blocking the main form from displaying over it (block the user from clicking the form below thus hiding the OpenFileDialog).
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
找到了!
与我一起工作的一位程序员同事提出了一个实际有效的简单解决方案。
不必在第三个线程上运行 OpenFileDialog,只需在主窗体(启动工作线程的窗体)上运行它。
它看起来像这样:
这样我阻止主窗体被单击,并且 OpenFileDialog 在 STA 线程中运行。
并且认为解决这个问题的是一名 C++ 程序员;-)
我希望这对某人有帮助......
Found it!
A fellow programmer working with me suggested a simple solution that actually worked.
Instead of running the OpenFileDialog on a third thread just run it on the main form (the one that started the worker thread.
It looks like this:
This way I block the main form from being clicked and the OpenFileDialog runs in a STA thread.
And to think the one that solved it is a C++ programmer. ;-)
I hope this will be helpful to someone...