Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke() is blocking

Tags:

From time to time my applications GUI stops redrawing. There a lot of threads that are firing all kinds of events (like timers or network data ready etc.). Also there are a lot of controls that are subscribing these events. Because of that, all the event handlers play the InvokeRequired/Invoke game. Now I figured out that when the GUI freezes a lot of threads are waiting for Invoke() to return. Looks like the message pump stopped pumping. The handlers look like this:

private void MyEventHandler( object sender, EventArgs e ) {     if ( InvokeRequired ) {         Invoke( new EventHandler( MyEventHandler ), sender, e );         return;     }      SetSomeStateVariable();     Invalidate(); } 

Any ideas?

Solution: BeginInvoke(). Looks like you should always use BeginInvoke() if you have lots of CrossThread-Events...

Thanks.

Thanks everybody.

EDIT: Looks like BeginInvoke() really solved it. No freezing until now.

like image 586
EricSchaefer Avatar asked Nov 13 '08 14:11

EricSchaefer


2 Answers

Invoke waits until the event is handled in the GUI thread. If you want it to be asynchronous use BeginInvoke()

like image 60
Lou Franco Avatar answered Sep 22 '22 03:09

Lou Franco


Deadlock perhaps? Do you make sure that the events are never fired while holding a lock?

Are you able to see this with a debugger attached? If so, make it freeze and then hit the "pause" button - and see what the UI thread is doing.

Note that if you are able to get away with BeginInvoke instead of Invoke, life is a bit easier as it won't block.

Also note that you don't need the "new EventHandler" bit - just

Invoke((EventHandler) MyEventHandler, sender, e); 

should be fine.

like image 38
Jon Skeet Avatar answered Sep 22 '22 03:09

Jon Skeet