12

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?

Jeff Yates
  • 58,658
  • 18
  • 135
  • 183
Daniel Peñalba
  • 27,557
  • 31
  • 124
  • 209

5 Answers5

23

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

Community
  • 1
  • 1
bentsai
  • 2,913
  • 1
  • 21
  • 27
7

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.

SqlRyan
  • 30,939
  • 32
  • 109
  • 190
4

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

Andrey
  • 56,384
  • 10
  • 111
  • 154
  • What kind of answer is this? I attached the process with the debugger, I paused and inspected the threads. This is the reason I know that the thread is in the first block of code, and the main thread is in the second one. – Daniel Peñalba Feb 25 '11 at 16:17
  • @Daniel Peñalba this is kind of solution that helps me. Because when you do this you can see exact lines where thread hangs. – Andrey Feb 25 '11 at 16:24
  • I did that. The highlighted line when I break all threads is `overlayAnimation.Visible = false;` but usually Visual Studio (almost 2003) stops in the previous line. Only sometimes, this is the reason I'm not sure if is that line or the previous one. – Daniel Peñalba Feb 25 '11 at 16:44
0

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.

Steed
  • 277
  • 3
  • 14
0

You have to use BeginInvoke inested Invoke see this Link

Community
  • 1
  • 1
alireza amini
  • 1,616
  • 1
  • 16
  • 33