I am having an issue with Control.BeginInvoke()
that does not happen every time. It seems to work well for 5 times or so, then becomes more of a 50/50 success rate after that.
What is happening is that I will call BeginInvoke()
on a control that has already been created and showing, and the call will not be executed on the GUI thread immediately. The invoking thread does immediately return from BeginInvoke()
and go on about its business. The delegate is not executed on the GUI thread until another BeginInvoke()
is executed on the control. Then it is as if it realizes it has something to do and finally does it. This can be over 10 minutes later.
Code
Here is the code that executes the BeginInvoke()
that does not execute the delegate immediately:
protected void DisplayPrompt(PromptData promptData)
{
Debug.WriteLine(DateTime.Now + ": Entering DisplayPrompt: " + Thread.CurrentThread.Name);
this.CurrentPrompt = promptData;
if (this.InvokeRequired)
{
Debug.WriteLine(DateTime.Now + ": Before BeginInvoke of DisplayPrompt: " + Thread.CurrentThread.Name);
this.BeginInvoke(new Action(() => this.DisplayPrompt(promptData)));
Debug.WriteLine(DateTime.Now + ": After BeginInvoke of DisplayPrompt: " + Thread.CurrentThread.Name);
return;
}
// The rest of the method goes here
}
What seems to kick the invoked method through the message pump is when the below code gets executed. This code gets executed after I get tired of waiting for the above delegate to be executed, and I press a button that ultimately calls ClearPrompt()
.
protected void ClearPrompt()
{
Debug.WriteLine(DateTime.Now + ": Entering ClearPrompt: " + Thread.CurrentThread.Name);
this.CurrentPrompt = null;
if (this.InvokeRequired)
{
Debug.WriteLine(DateTime.Now + ": Before BeginInvoke of ClearPrompt: " + Thread.CurrentThread.Name);
this.BeginInvoke(new Action(() => this.ClearPrompt()));
Debug.WriteLine(DateTime.Now + ": After BeginInvoke of ClearPrompt: " + Thread.CurrentThread.Name);
return;
}
// The rest of the method goes here
}
And finally, here is the output:
11/13/2013 1:16:49 PM: Entering DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: Before BeginInvoke of DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: After BeginInvoke of DisplayPrompt: BatchStateMachine
The thread 0x998 has exited with code 0 (0x0).
The thread 0x1174 has exited with code 0 (0x0).
11/13/2013 1:27:01 PM: Entering ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Before BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: After BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Entering DisplayPrompt:
11/13/2013 1:27:01 PM: Entering ClearPrompt:
It's the second Entering DisplayPrompt
at 1:27:01 PM
that is where the GUI is finally running the delegate.
Question:
So I guess the question is, what could cause BeginInvoke()
to have this delayed behavior, and what can I do to better debug this?
Other notes:
- These methods belong to an instance of a
UserControl
object - The
UserControl
object has existed and has been displayed for several minutes before the code has ran, i.e. the control handle should exist. - I have used
BeginInvoke()
successfully just like this many times before - The GUI seems to be fully responsive during the period in which the delegate should be ran. GUI controls are updating, I can navigate the application, etc.
Thanks!