InvalideOperationException / invoke

The following code is used to start the call (the code is reduced, in this example I did not take into account error handling) to make it more understandable.

public static void InvokeIfNecessary(this Control control, MethodInvoker methodInvoker) { if (control != null && !control.IsDisposed && !control.Disposing) { if (control.InvokeRequired) { control.Invoke(methodInvoker); } else { methodInvoker(); } } } 

It usually works fine, but sometimes, if I call a form method, an InvalidOperationException is thrown. The schematic method to be called

 // 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(); }); } } 

Well ... I have to admit that I have a conceptual problem.

Why is the Exception selected here?

The Frm2 method creates a new element (in NO there is only a line and a structure with lines and a bool). The item is available only in the UpdateSomething () method. The layOutControlGroup team is a member of Frm2.

So, in my opinion, only the special control that is created in the Frm2 stream must be bound to a specific Frm2 control.

So why does he insist on FrmMain? (the main form that invokes the form method to inform you about updating items)

PS this.InvokeIfRequired <- this is Frm2 actually ...

+1
source share
2 answers

So, as we see, there are always problems with (begin) invoke. Use BeginInvoke instead. this is my hint. Usually he says that begin invoke on controls executes the method in the same thread where the descriptor was created.

But, as it seems, the form2 handle was not created in the same thread, or perhaps it is not there yet. Try checking it out and checking it out.

Oh. by the way, flag exceptions, clr, in the visual studio when they are thrown. This helps to detect the error.

0
source

I think you checked InvokeRequired with the wrong control.

What you needed to check with InvokeRequired is layoutControlGroup , but your extension method checks the form with this.InvokeIfNecessary code, where this is Frm2.

Also, you called layoutControlGroup.BeginUpdate() , but layoutControlGroupCA.EndUpdate() seems unbalanced to use.

Code correction can be:

 internal void UpdateSomething() { var myObjects=frmMain.NO.GetNOs(); if(null!=myObjects) { MethodInvoker beginUpdate=() => layoutControlGroup.BeginUpdate(); MethodInvoker endUpdate=() => layoutControlGroup.EndUpdate(); layoutControlGroup.InvokeIfNecessary(beginUpdate); foreach(NO aObject in myObjects) if(SomeCondition) { // update } else { LayoutControlItem layoutControlItem=new LayoutControlItem(); Control control=CreateNewControl(aObject); layoutControlItem.Control=control; MethodInvoker addItem= () => { layoutControlGroup.AddItem(layoutControlItem); }; layoutControlGroup.InvokeIfNecessary(addItem); } layoutControlGroup.InvokeIfNecessary(endUpdate); } } 
0
source

All Articles