As much as the CLR team assures us that it's ok to fire-and-forget
Control.BeginInvoke, it seems it isn't. Maybe this is a bug.
See for example: the comments in
http://blogs.msdn.com/cbrumme/archiv.../06/51385.aspx
I was encountering a bug that disappeared when debugging. Not when a
debugger is attached, mind you, but when I placed a breakpoint near the
code. Adding Trace.WriteLine statements showed that the failing code was
not even being executed. Ok, what effects can a breakpoint have? Well,
evaluation of watch expressions, so I cleared the watch window... check,
same behavior. And occasionally (<10%) the code worked even with the
breakpoint removed or disabled. Must be a race condition, hitting a
breakpoint could definitely affect thread scheduling.
Turns out this code (now fixed) was the culprit:
if (postProcessing != null)
{
new UIPermission(UIPermissionWindow.AllWindows).Assert ();
Control c = new Control();
IntPtr forceHandleCreation = c.Handle;
MethodInvoker finalProcessing = postProcessing + c.Dispose;
helper.postProcessing = delegate {
c.Invoke(finalProcessing); };
}
new System.Threading.Thread(helper.UIThreadProc).Start ();
The thread procedure:
public void UIThreadProc()
{
new UIPermission(UIPermissionWindow.AllWindows).Assert ();
progressDialog = new
ProgressTracker((ushort)fileArray.Length, cumulativeSize, actionMsg);
IntPtr forceHandleCreation = progressDialog.Handle;
new System.Threading.Thread(WorkThreadProc).Start();
Application.Run(progressDialog);
if (postProcessing != null)
postProcessing();
}
I originally had c.BeginInvoke in the asynchronous method. Seems that if
you BeginInvoke and then the calling thread ends, the call never takes
place. Yuck!
Do you think this is a CLR bug or it is by design?