Friday, January 7, 2011

How to wrap InvokeRequired in WinForms using Extension Methods

Recently I saw a win form application that needs to print data to the UI from different threads.

As you probably know, for changing controls from a different thread other than the UI you need to use the InvokeRequired property of the control and then Control.Invoke method.

My very good friend Assaf had a very nice solution to the problem which is based on Extension Methods and lambdas. 

This is his solution:
public static class WinformExtenstions {
   public static void Write(this TControl control, Action action)where TControl:Control{
         if (control.InvokeRequired) {
            control.Invoke(action, control);
         } else{
            action(control);
         }
      }

      public static TValue SafeRead(this TControl control, Func action) where TControl : Control{
         if (control.InvokeRequired) {
            return (TValue)control.Invoke(action, control);
         }
         return action(control);
      }
}
This is an example of how to use:

public partial class Form1 : Form {
      readonly Timer _timer;
      public Form1() {
         InitializeComponent();
         _timer = new Timer(500);
         _timer.Elapsed += TimerElapsed;
      }

      void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e) {
         textBox1.Write(control => { control.Text = DateTime.Now.ToString(); });
      }

      private void Form1_Load(object sender, EventArgs e) {
         _timer.Start();
      }
   }

I think this is a very elegant solution to the problem.

Hope this post was helpful

Gur

2 comments:

  1. Yeah I can see that your friend Assaf has told you very good solution to the problem. He is looking to be expert in Extension Methods and lambdas. I just tried it..it is working absolutely fine.
    digital signature software

    ReplyDelete
  2. STC Technologies's USP is that we deliver certification programs and not courses. STC Technologies

    ReplyDelete