Reputation: 31847
I'm showing an animation while my control is loading the data. When the thread finishes, I hide the animation and show the control. So I'm executing this code from a thread:
protected void InvokeEnableBackControl()
{
if (this.InvokeRequired)
{
this.Invoke(new OpHandler(EnableBackControl));
}
else
{
EnableBackControl();
}
}
Sometimes, when I execute this code, the main thread gets hanged in the following code:
protected virtual void EnableBackControl()
{
if (overlayAnimation.TargetControl != null)
{
overlayAnimation.TargetControl.BringToFront();
}
overlayAnimation.SendToBack();
overlayAnimation.Enabled = false;
overlayAnimation.Visible = false;
}
I'm not sure if it's hanged setting the Enable
or Visible
property. Do you know any circumstance that may hand the application calling these properties from a Control.Invoke
?
Upvotes: 12
Views: 19315
Reputation: 287
What I discovered is that the actual drawing/painting of controls can be quite slow, esp if you have a lot of them and/or use double buffering for smooth refresh. I was using BeginInvoke to update a listview control from data I was receiving from a socket. At times the updates were happening so fast that it was freezing the app up. I solved this by writing everything I received in the sockets async receive to a queue, and then in a seperate thread dequeuing the data and using BeginUpdate and EndUpdate on the listview and doing all the outstanding updates in between. This cut out a ton of the extra redrawing and made the app a lot more responsive.
Upvotes: 0
Reputation: 33914
I've run into problems before when I'm executing .Invoke on a background thread while my main thread is still busy - this gives the impression that the app is hung, because the .Invoke just sits there, waiting for the main thread to respond that it's paying attention. Possible causes:
When you attach the debugger, pay special attention to what your main control MessagePump thread is doing - I suspect its lack of attention is the cause of your trouble. If you identify that it's a tight loop in your main thread that's not responding, try inserting a .DoEvents
in the loop, which will pause execution and force the main thread to empty the message pump and route any outstanding requests.
Upvotes: 9
Reputation: 3133
Note that Control.Invoke
is synchronous, so it will wait for EnableBackControl()
to return. Consider using Control.BeginInvoke
, which you can "fire and forget."
See this answer: What's the difference between Invoke() and BeginInvoke()
Upvotes: 27
Reputation: 60055
Run in debug, make app hang and then pause debug in Visual Studio and inspect threads.
Upvotes: 4