Make InvokeRequired/Invoke easy

Posted on : 23-01-2009 | By : manitra | In : C#, Developpement, WinForm

7

The problem

If you’re working on WinForms, you must know that you cannot call controls methods within a thread that is not the one that created those controls. To solve this problem, Microsoft recommend us to use the following code :

  1. namespace TestWinForm
  2. {
  3.     public partial class MainForm : BaseForm
  4.     {
  5.         public MainForm()
  6.         {
  7.             InitializeComponent();
  8.         }
  9.         // a delegate that has been created specially for this method
  10.         private delegate void DisplayDelegate(string text);
  11.  
  12.         // a method that may be called from a worker thread
  13.         public virtual void Display(string text)
  14.         {
  15.             if (InvokeRequired)
  16.             {
  17.                 Invoke(new DisplayDelegate(Display));
  18.             }
  19.             else
  20.             {
  21.                 //the actual job is here
  22.                 textBox1.AppendText(text);
  23.             }
  24.         }
  25.     }
  26. }

This code is ugly because :

  • you need to create a delegate for each single public method you can call from outside
  • you need to put an “if/else” block in each method wich increase the complexity of your code

The trick

Here is a trick that could significantly reduce the amount of code needed to do the same job within a large project.

Within you base class

You probably have a common base class for all your UI components. Add this method :

  1. namespace TestWinForm
  2. {
  3.     public class BaseForm : Form
  4.     {
  5.         // This allows a sub class to easily run a method within
  6.         // an UI thread without the need of creating multiple
  7.         // delegate signatures for each method signatures
  8.         protected virtual void ThreadSafe(MethodInvoker method)
  9.         {
  10.             if (InvokeRequired)
  11.                 Invoke(method);
  12.             else
  13.                 method();
  14.         }
  15.     }
  16. }

Within your UI classes

Now the only thing you need to do is to encapsulate the methode content with the ThreadSafe() method :

  1. namespace TestWinForm
  2. {
  3.     public partial class MainForm : BaseForm
  4.     {
  5.         public MainForm()
  6.         {
  7.             InitializeComponent();
  8.         }
  9.  
  10.         // public method that may be called from outside and within any
  11.         // worker thread …
  12.         public virtual void Display(string text)
  13.         {
  14.             ThreadSafe(delegate
  15.             {
  16.                 //do any UI related code here
  17.                 //note that because this is an anonym method,
  18.                 //you can use the local parameter
  19.                 textBox1.AppendText(text);
  20.             });
  21.         }

Happy coding !

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Netvibes
  • Technorati
  • TwitThis

Comments (7)

What if I want the Display method to be public? it cant because of being virtual..

Sorry I meant to said “..the display method to be private”

Hi German,

The Display() can have any modifier on it, it does’nt matter.

You could make it ‘private’ and remove the ‘virtual’ keyword if you don’t want other classes to have access to it.

Manitra.

Good method ;-)
Thanks to share this idea

Wow! This looks like a very nice and neat solution. Thank you for taking the tme to write this post.

I have been looking at another approach where you decorate a function with with attribute as described here: http://weblogs.asp.net/rosherove/archive/2007/05.aspx?PageIndex=2

.. The solution works a treat but requires you to add 3 dlls to your projeect to achieve this!

Very great post. I simply stumbled upon your weblog and wished to
mention that I’ve really loved surfing around your blog posts.
After all I’ll be subscribing to your feed and I hope you
write once more very soon!

Here is my weblog carpet shampooer reviews Victoria

Undeniably believe that which you said. Your favorite justification appeared to be on the net
the easiest thing to be aware of. I say to you, I definitely get irked while people consider
worries that they plainly don’t know about. You managed to hit
the nail upon the top as well as defined out the whole thing without having side-effects ,
people could take a signal. Will probably be back to get
more. Thanks

Here is my web page … How To Repair Foundation Denver CO

Write a comment