【发布时间】:2010-07-23 00:35:37
【问题描述】:
我有一个函数可以将控件添加到父控件,该控件是从与创建控件的线程不同的线程调用的。事情是这样的:
1 delegate void AddControlToParentDelegate(Control child, Control parent);
2 private void addControlToParent(Control child, Control parent) {
3 if (parent.InvokeRequired) {
4 AddControlToParentDelegate d = new AddControlToParentDelegate(addControlToParent);
5 this.Invoke(d, new object[] { child, parent });
6 } else {
7 parent.Controls.Add(child);
8 }
9 }
10 }
在 parent.InvokeRequired 和 child.InvokeRequired 都为 TRUE 之前,这可以正常工作。然后,一旦执行了第 5 行(现在调用了委托d,并且该函数应该在 UI 线程上运行。(对吗?))第 7 行的child 会引发跨线程操作无效异常。为什么是这样?它不是已经在它创建的线程上运行了吗?
我设法通过添加一个额外的(child.InvokeRequired) 检查来解决这个问题:
delegate void AddControlToParentDelegate(Control child, Control parent);
private void addControlToParent(Control child, Control parent) {
if (parent.InvokeRequired) {
AddControlToParentDelegate d = new AddControlToParentDelegate(addControlToParent);
this.Invoke(d, new object[] { child, parent });
} else {
if (child.InvokeRequired) {
this.Invoke(new MethodInvoker(delegate() {
parent.Controls.Add(child);
}));
} else {
parent.Controls.Add(child);
}
}
}
但这似乎非常骇人听闻且不必要。这是这样做的方法吗?还是我完全错过了公共汽车?
【问题讨论】:
标签: c# winforms invoke multithreading