Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control.Invoke() hangs application

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?

like image 226
Daniel Peñalba Avatar asked Feb 25 '11 15:02

Daniel Peñalba


3 Answers

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()

like image 120
bentsai Avatar answered Oct 21 '22 12:10

bentsai


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:

  • Your main thread is blocked waiting for something
  • Your main form currently had a modal dialog up, so it's not listening to new requests
  • Your main thread is spinning, either continually checking if something is finished or doing new work. In my case, the main thread spent the first minute spinning up background threads in a tight loop, so it wasn't listening for any .Invoke requests from background threads.

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.

like image 22
SqlRyan Avatar answered Oct 21 '22 12:10

SqlRyan


Run in debug, make app hang and then pause debug in Visual Studio and inspect threads.

like image 27
Andrey Avatar answered Oct 21 '22 11:10

Andrey