我一直在为此奋斗了很长一段时间: 我有一个功能用于将控件添加到具有跨线程处理的面板,但问题是虽然面板和控件处于“InvokeRequired = false”状态 - 我得到一个异常,告诉我其中一个控件内部控件是从其创建的线程以外的线程访问的,片段如下所示:内部控件的“跨线程操作无效”异常
public delegate void AddControlToPanelDlgt(Panel panel, Control ctrl);
public void AddControlToPanel(Panel panel, Control ctrl)
{
if (panel.InvokeRequired)
{
panel.Invoke(new AddControlToPanelDlgt(AddControlToPanel),panel,ctrl);
return;
}
if (ctrl.InvokeRequired)
{
ctrl.Invoke(new AddControlToPanelDlgt(AddControlToPanel),panel,ctrl);
return;
}
panel.Controls.Add(ctrl); //<-- here is where the exception is raised
}
异常消息是这样的:
“交叉线程操作无效:控制“pnlFoo”从比它的”
创建的线程以外的线程访问(‘pnlFoo’是ctrl.Controls下)
我如何添加Ctrl键面板? !
当代码到达“panel.Controls.Add(ctrl);”时,行 - 面板和ctrl“InvokeRequired”属性设置为false,问题是控件里面的ctrl“InvokeRequired”设置为true。为了澄清一些事情:在基线上创建“panel”,在新线程上创建“ctrl”,因此必须调用“panel”(导致“ctrl”需要再次调用)。一旦两个调用完成,它就会到达panel.Controls.Add(ctrl)命令(在这个状态下“panel”和“ctrl”都不需要调用)
这是一个完整的小代码片段程序:
public class ucFoo : UserControl
{
private Panel pnlFoo = new Panel();
public ucFoo()
{
this.Controls.Add(pnlFoo);
}
}
public class ucFoo2 : UserControl
{
private Panel pnlFooContainer = new Panel();
public ucFoo2()
{
this.Controls.Add(pnlFooContainer);
Thread t = new Thread(new ThreadStart(AddFooControlToFooConatiner());
t.Start()
}
private AddFooControlToFooConatiner()
{
ucFoo foo = new ucFoo();
this.pnlFooContainer.Controls.Add(ucFoo); //<-- this is where the exception is raised
}
}
这里是程序: public class ucFoo:UserControl { private Panel pnlFoo = new Panel(); public ucFoo() { this.Controls.Add(pnlFoo); } } public class ucFoo2:UserControl { private Panel pnlFooContainer = new Panel(); public ucFoo2() {this.Controls.Add(pnlFooContainer);线程t =新线程(new ThreadStartAddFooControlToFooConatiner()); t.Start(); } private AddFooControlToFooConatiner() { ucFoo foo = new ucFoo(); this.pnlFooContainer.Controls.Add(ucFoo); // < - 这是发生异常的地方 } } – Nissim 2009-06-10 09:09:57
我添加了片段作为更好阅读的答案 – Nissim 2009-06-10 09:13:16