Yes, we create secondary threads and those threads do call Control.Invoke
for updating UI. However, I see no reason
why those Control.Invoke calls should be dispatched to any thread other than
the primary thread.

The problem is almost 100% reproducible, and during the last debugging
session I noticed only two managed threads:
the first one is the primary thread with the stack trace I posted in the
original message, and the second one is a background
worker thread which performs jobs in the background. However, the background
thread is simply waiting for new jobs, it doesn't have
any windows associated with it, and it never calls Control.Invoke.

> -----Original Message-----
> From: Discussion of advanced .NET topics.
> [mailto:[EMAIL PROTECTED] On Behalf Of
> Fabian Schmied
> Sent: Thursday, February 23, 2006 2:06 PM
> To: [email protected]
> Subject: Re: [ADVANCED-DOTNET] Odd stack trace from a hung .NET app
>
> > Could you please clarify what makes you think that the target UI
> > thread differs from the original thread?
>
> I took a look at Control.MarshaledInvoke in Reflector (code is below).
>
> First, MarshaledInvoke creates an "entry1" variable holding
> the event handler method and marshals it (i.e. enqueues it in
> a control-internal queue). Then, MarshaledInvoke checks
> whether the current thread is the same as the UI thread of
> the target control and sets "flag1"
> accordingly. If flag1 is set (i.e. if we are currently on the
> right UI thread), the marshaled methods are executed
> immediately(InvokeMarshaledCallbacks), else a message is
> posted to inform the control's WndProc that it should handle
> the marshaled methods (threadCallbackMessage). If the call
> was asynchronous, the method returns immediately. If not, it
> checks whether the method "entry1" is completed. If we were
> on the UI thread, it would be completed now (we would have
> executed it on the current thread earlier), but it isn't,
> because your breakpoint was in WaitForWaitHandle.
>
> Therefore my conclusion that MarshaledInvoke seems to think
> it is on the wrong thread - whether this is correct or not, I
> can't say.
>
> Code:
>
> [...]
>   Control.ThreadMethodEntry entry1 = new
> Control.ThreadMethodEntry(caller, method, args, synchronous,
> context1); [...]
>     this.threadCallbackList.Enqueue(entry1);
> [...]
> if ((SafeNativeMethods.GetWindowThreadProcessId(new
> HandleRef(this, this.Handle), out num1) ==
> SafeNativeMethods.GetCurrentThreadId()) &&
> synchronous)
>       {
>             flag1 = true;
>       }
> [...]
>  if (flag1)
>       {
>             this.InvokeMarshaledCallbacks();
>       }
>       else
>       {
>             UnsafeNativeMethods.PostMessage(new
> HandleRef(this, this.Handle), Control.threadCallbackMessage,
> IntPtr.Zero, IntPtr.Zero);
>       }
> [...]
>   if (!synchronous)
>       {
>             return entry1;
>       }
>       if (!entry1.IsCompleted)
>       {
>             this.WaitForWaitHandle(entry1.AsyncWaitHandle);
>       }
> [...]
>
> > Actually, we don't create (at least, explicitly) controls or other
> > windows on secondary threads, so this hardly is the case.
>
> Do you create any other threads? And do any of those call
> Control.Invoke?
>
> Fabian
>
> ===================================
> This list is hosted by DevelopMentorR  http://www.develop.com
>
> View archives and manage your subscription(s) at
> http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to