Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.
MethodInvoker provides a simple delegate that is used to invoke a method with a void parameter list. This delegate can be used when making calls to a control's Invoke method, or when you need a simple delegate but do not want to define one yourself.
Create the delegate and matching procedures Create a delegate named MySubDelegate . Declare a class that contains a method with the same signature as the delegate. Define a method that creates an instance of the delegate and invokes the method associated with the delegate by calling the built-in Invoke method.
Lee's approach can be simplified further
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
    // See Update 2 for edits Mike de Klerk suggests to insert here.
    if (control.InvokeRequired) {
        control.Invoke(action);
    } else {
        action();
    }
}
And can be called like this
richEditControl1.InvokeIfRequired(() =>
{
    // Do anything you want with the control here
    richEditControl1.RtfText = value;
    RtfHelpers.AddMissingStyles(richEditControl1);
});
There is no need to pass the control as parameter to the delegate. C# automatically creates a closure.
If you must return a value, you can use this implementation:
private static T InvokeIfRequiredReturn<T>(this Control control, Func<T> function)
{
    if (control.InvokeRequired) {
        return (T)control.Invoke(function);
    } else {
        return function();
    }
}
UPDATE:
According to several other posters Control can be generalized as ISynchronizeInvoke:
public static void InvokeIfRequired(this ISynchronizeInvoke obj,
                                         MethodInvoker action)
{
    if (obj.InvokeRequired) {
        var args = new object[0];
        obj.Invoke(action, args);
    } else {
        action();
    }
}
DonBoitnott pointed out that unlike Control the ISynchronizeInvoke interface requires an object array for the Invoke method as parameter list for the action.
UPDATE 2
Edits suggested by Mike de Klerk (see comment in 1st code snippet for insert point):
// When the form, thus the control, isn't visible yet, InvokeRequired  returns false,
// resulting still in a cross-thread exception.
while (!control.Visible)
{
    System.Threading.Thread.Sleep(50);
}
See ToolmakerSteve's and nawfal's comments below for concerns about this suggestion.
You could write an extension method:
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
    if(c.InvokeRequired)
    {
        c.Invoke(new Action(() => action(c)));
    }
    else
    {
        action(c);
    }
}
And use it like this:
object1.InvokeIfRequired(c => { c.Visible = true; });
EDIT: As Simpzon points out in the comments you could also change the signature to:
public static void InvokeIfRequired<T>(this T c, Action<T> action) 
    where T : Control
    Here's the form I've been using in all my code.
private void DoGUISwitch()
{ 
    Invoke( ( MethodInvoker ) delegate {
        object1.Visible = true;
        object2.Visible = false;
    });
} 
I've based this on the blog entry here.  I have not had this approach fail me, so I see no reason to complicate my code with a check of the InvokeRequired property.
Hope this helps.
Create a ThreadSafeInvoke.snippet file, and then you can just select the update statements, right click and select 'Surround With...' or Ctrl-K+S:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>ThreadsafeInvoke</Title>
    <Shortcut></Shortcut>
    <Description>Wraps code in an anonymous method passed to Invoke for Thread safety.</Description>
    <SnippetTypes>
      <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Code Language="CSharp">
      <![CDATA[
      Invoke( (MethodInvoker) delegate
      {
          $selected$
      });      
      ]]>
    </Code>
  </Snippet>
</CodeSnippet>
    Here's an improved/combined version of Lee's, Oliver's and Stephan's answers.
public delegate void InvokeIfRequiredDelegate<T>(T obj)
    where T : ISynchronizeInvoke;
public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action)
    where T : ISynchronizeInvoke
{
    if (obj.InvokeRequired)
    {
        obj.Invoke(action, new object[] { obj });
    }
    else
    {
        action(obj);
    }
} 
The template allows for flexible and cast-less code which is much more readable while the dedicated delegate provides efficiency.
progressBar1.InvokeIfRequired(o => 
{
    o.Style = ProgressBarStyle.Marquee;
    o.MarqueeAnimationSpeed = 40;
});
    
                If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With