我一直在爲此奮鬥了很長一段時間: 我有一個功能用於將控件添加到具有跨線程處理的面板,但問題是雖然面板和控件處於「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