If Control.InvokeRequired is always used when accessing user interface controls

We are building a .NET application using WinForms (3.5).

I recently added a new feature and began to experience strange behavior when accessing certain controls. The problem was that some access to the user interface simply stopped execution (an exception was not visible).

In close analysis (using WinDbg), I realized that the controls were updated from the ThreadPool thread, and a CrossThreadMessagingException was thrown.

My question is: is there any good practice on how to get around this behavior?

It would be very cumbersome, but perhaps it would not be possible to surround every location of the code that accesses the user interface elements using the Control.Invoke method.

How can I split my code into “safe” code that Invoke should not use from that which should?

+5
source share
1 answer

, , - , , , InvokeRequired , re-Invoke() , , , . , InvokeRequired ( , / ); - , Load(), Closing(), , , .

( BackgroundWorkers, TPL-, BeginInvoke() Start() ), . InvokeRequired ( - , WinAPI GetThreadId GetWindowThreadProcessId ), , , , :

//no return value, no parameters; ShowWindow(), HideWindow(), etc
//Understand that many built-in control methods are not virtual and so you can't 
//override them to do this; you must either hide them or ensure the caller is
//checking for cross-threading.
public void MyWindowMethod()
{
   if(InvokeRequired)
      this.Invoke(new Action(MyWindowMethod));
   else
   {
      //main logic
   }
}

//Input but no return; SetTitle("My Title")
public void MyWindowMethod2(string input)
{
   if(InvokeRequired)
      this.Invoke(new Action<string>(MyWindowMethod2), input);
   else
   {
      //main logic
   }
}

//inputs and outputs; custom methods, advanced graphics
public string MyWindowMethod3(string input)
{
   if(InvokeRequired)
      return (string)(this.Invoke(new Func<string, string>(MyWindowMethod3), input));

   //No else required; the return makes it redundant
   //main logic   
}
+8

All Articles