以下代码用于触发调用(代码减少,我在此示例中省略了错误处理以使其更清晰)
public static void InvokeIfNecessary(this Control control, MethodInvoker methodInvoker)
{
if (control != null && !control.IsDisposed && !control.Disposing)
{
if (control.InvokeRequired)
{
control.Invoke(methodInvoker);
}
else
{
methodInvoker();
}
}
}
通常它工作正常,但有时如果我调用 Form 的方法,则会给出 InvalidOperationException。要调用的示意方法
// in a Frm2:
internal void UpdateSomething()
{
List<NO> myObjects = frmMain.NO.GetNOs();
if (null != myObjects)
{
this.InvokeIfNecessary(() =>
{
layoutControlGroup.BeginUpdate(); // DevExpress Layoutcontrolgroup
foreach (NO aObject in myObjects)
{
if(...) // if already a control for the object exist update it.
{
// update
}
else
{
// add item
LayoutControlItem layoutControlItem = new LayoutControlItem();
// create new control
Control control = CreateNewControl(aObject);
layoutControlItem.Control = control;
// do some stuff with visibility and size of control
...
layoutControlGroup.AddItem(layoutControlItem); // <-- And here the InvalidOperationException occurs.
/// The message is (translated
/// InvalidOperationException was not handled by usercode
/// The acces on the Control FrmMain was done from another Thrad then the thread which created it.
...;
}
}
...;
layoutControlGroupCA.EndUpdate();
});
}
}
嗯......我必须承认我在这里有一个概念问题。
为什么这里会抛出异常?
Frm2 方法创建一个新元素(在 NO 中只有一个字符串和一个带有字符串和布尔值的结构)。该元素只能在 UpdateSomething() 方法中访问。layoutControlGroup 是 Frm2 的成员。
所以在我看来,只有应该在 Frm2 线程中创建的新控件应该附加到 Frm2 特定控件。
那么它为什么坚持在 FrmMain 中呢?(主窗体,它调用窗体的方法来通知项目的更新)
PS this.InvokeIfRequired <- 这实际上是 Frm2 ......