我有一个主UI线程,它运行应用程序并创建主窗口表单(让我们称之为W
)。我还有一个我旋转的辅助线程,它创建了一个对话框(让我们称之为B
)。
我想将对话框B
的所有者设置为主窗口W
。 B
所有者的设置发生在创建B
的线程上。基本上是:
b.Owner = w;
但是这会引发一个跨线程异常,告诉我我正在尝试从错误的线程访问W
对象。
所以我尝试在Control.Invoke
W
上使用B
来执行主UI线程上的代码。但是,我得到了同样的错误,告诉我我正试图从错误的线程访问System.InvalidOperationException was unhandled by user code
Message=Cross-thread operation not valid: Control 'B' accessed from a
thread other than the thread it was created on.
Source=System.Windows.Forms
:
{{1}}
我该怎么做?
答案 0 :(得分:5)
这是Winforms中的一个错误,Windows实际上支持使所有者成为在另一个线程上创建的窗口。有一种方法可以禁用该检查,您应该永远做的事情。除非我不得不假设:
private void button1_Click(object sender, EventArgs e) {
var t = new Thread(() => {
Control.CheckForIllegalCrossThreadCalls = false;
var frm = new Form2();
frm.Show(this);
Control.CheckForIllegalCrossThreadCalls = true;
Application.Run(frm);
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
我不知道这是否100%安全,可能有一个Winforms交互搞砸了。你在这里没有经过测试的水域,感染了鲨鱼。
答案 1 :(得分:3)
B
。
您仍然可以使用B
从辅助线程与Control.Invoke
进行互动。
答案 2 :(得分:2)
如果你实际上在不同的线程上运行了两个消息循环,那么就没有办法完成你所追求的了。如果您希望W
拥有B
,则必须在主要帖子上创建B
,并Invoke
与B
进行所有互动第二个主题。