我已经苦苦挣扎了相当长一段时间: 我有一个函数,旨在添加控件到具有跨线程处理功能的面板上,问题是尽管面板和控件都处于“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中?!
当代码执行 "panel.Controls.Add(ctrl);" 这行时 - panel 和 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
}
}