Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Using Anonymous Methods with Control.Invoke()

 

Just in case I'm the only person that didn't know this, you can't pass an anonymous method as an argument to Control.Invoke() when you're trying to make cross-thread calls.  Instead, you have to wrap it in a Delegate like the MethodInvoker delegate like this code below:

 

   23         public string CurrentActivity

   24         {

   25             get { return _activityStrip.Text; }

   26             set

   27             {

   28                 if (InvokeRequired)

   29                 {

   30                     MethodInvoker invoker = new MethodInvoker(delegate()

   31                                                                   {

   32                                                                       _activityStrip.Text = value;

   33                                                                   });

   34                     Invoke(invoker);

   35                 }

   36                 else

   37                 {

   38                     _activityStrip.Text = value;

   39                 }

   40             }

   41         }

It's fine and it works, but it's butt ugly.  I'm mildly tempted to try out Boo for this very reason or maybe play with RubyCLR to drive WinForms with a cleaner syntax.


Posted 11-05-2006 8:49 PM by Jeremy D. Miller

[Advertisement]

Comments

Geert Baeyaert wrote re: Using Anonymous Methods with Control.Invoke()
on 11-06-2006 4:18 AM

You can also cast the anonymous delegate to MethodInvoker.

Invoke((MethodInvoker)delegate() { _activityStrip.Text = value; });

Still not ideal, but better.

David M. Kean wrote re: Using Anonymous Methods with Control.Invoke()
on 11-06-2006 8:50 PM

Or why don't you add an overload to your base Form that takes a MethodInvoker:

public void Invoke(MethodInvoker invoker)

{

           Invoke((Delegate)invoker);

}

Now you can call Invoke with an anonymous method.

Bhavesh wrote re: Using Anonymous Methods with Control.Invoke()
on 12-05-2006 4:56 AM

I still think is has performance issues.

I have taken an example to update progressbar while reading a huge file. If I update in unsafe way in the thread, the program executes amazingly fast.

MethodInvoker myCallback = new MethodInvoker(

               delegate()

{

progressBar1.Value = m_iPercentage;

});

//progressbar percentage

Double perRead = (Convert.ToDouble(fStream.Position) / Convert.ToDouble(fStream.Length)) * 100.0;

m_iPercentage = Convert.ToInt32(perRead);

progressBar1.Value = m_iPercentage;

//Invoke(myCallback);

as soon as i comment progressbar1.value = m_iPercentage; and run through Invoke(myCallback); the program runs hell lot slower.

Do know what to do here.

Myrddin wrote re: Using Anonymous Methods with Control.Invoke()
on 12-13-2006 4:12 AM

Try using BeginInvoke instead so your thread doesn't block waiting for the target thread's message loop.

Myrddin wrote re: Using Anonymous Methods with Control.Invoke()
on 12-13-2006 4:16 AM

Also, you really should keep track of your last percentage and avoid doing the invoke all together unless the value has changed.  Invokes by their very nature are slow and even if you don't block on them it'll be better for your application if you don't invoke unless you absolutely have to.

Jonathon Rossi wrote Calling Control.Invoke() with anonymous methods
on 03-02-2008 7:21 AM

Calling Control.Invoke() with anonymous methods

Dana Hanna wrote re: Using Anonymous Methods with Control.Invoke()
on 05-20-2008 2:34 PM

In 3.5, you could create a simple extension method on the Control object with this overload which will allow a anony delegate to be passed to invoke:

public static void Invoke(this Control c, MethodInvoker mi)

{

   c.Invoke((Delegate)mi);

}

Blair Davidson wrote re: Using Anonymous Methods with Control.Invoke()
on 06-21-2009 10:36 AM

get { return _activityStrip.Text; }

is that threadsafe???

doesnt look like it

i wrap get and sets with invokes

Add a Comment

(required)  
(optional)
(required)  
Remember Me?