Hi Stoitcho,
I don't want to start a long discussion on this complicated subject before
you did read the sources[1], I'm not sure this can even be discussed in
great detail in a public forum without me breaking some NDA.
See inline ****
Willy.
Stoitcho Goutsev (100) said:
Hi Willy,
Where did you get that information. I doesn't make any sense to me. If you
have any sources (links, books, articles, etc) I'll appreciate if you post
them here.
****
[1] Here are the links, most notably chris brummes blogs will be enlightning
http://blogs.msdn.com/cbrumme/archive/2004/02/20/77460.aspx
http://blogs.msdn.com/cbrumme/archive/2004/02/20/77460.aspx
http://blogs.msdn.com/maoni/archive/2004/11/04/252697.aspx
Another great source of info are the VM source files, I have access to the
MSFT .NET sources (no, not Rotor) files through the Code Center Premium
license.
and :
http://support.microsoft.com/default.aspx?scid=kb;en-us;828988
See my opinion inlined
CLR cannot perform any pumping simply because the pumping has to be done
by the UI thread itself. It is blocked to perform pumping means that the
thread needs to be unblocked and let executing the code. That is exactly
what the programmer called Join wants to avoid. What if the execution
loops back and executes the same lines of code thus, instantiate and start
new thread and call new Join. If this is possible why one would block the
main thread one simply can let the main thread go.
Once the thread is blocked that's it it is blocked, period.
**** Beware the difference between a logical (CLR) and a physical
(OS)thread. The CLR hijacks the UI thread (OS) when calling Join(), this is
not the same as blocking a thread at the OS level. (Note: UI thread here
means a thread with a HWND associated, not necessarily a visible windows)
(2). One of the reasons for
Indeed. That exactly what happens. The finalizer thread blocks as well as
the thread calling WaitForPandingFinalizers. Deadlock!?! Well, not exactly
because CLR gives certain amount of time for all finalizers to finish. If
some of the finalizers are not executed... well, too bad for them.
There is KB article addressing this issue:
http://support.microsoft.com/default.aspx?scid=kb;en-us;828988
**** Did you read the complete article, this is a snip taken from the bottom
of the page:
If you must use STA threads to create COM components, the STA threads must
pump messages regularly. To pump messages for a short time, call the
Thread.Join method, as follows:
Thread.CurrentThread.Join(100)This method call pumps messages for 100
milliseconds. You can adjust the time-out based on the requirements of the
application. Also, the STA thread should never perform unbounded non-pumping
operations, such as calling Console.ReadLine. Instead, the STA thread must
have a MTA thread perform the operation and then wait for the operation to
finish.
REFERENCES
Non-UI thread doesn't pump because they don't have message queue. That's
why they are called non-UI.
Further more non-UI STA threads cannot host (create) COM objects simply
because STA apartment marshal's via windows messages thus, the thread has
to have message queue (UI thread)
*** Not exactly, OLE checks if the thread has a window handle associated
when entering an STA, if not OLE creates a hidden window and a message
queue. But, you have to pump messages of course. Remember: One of the rules
of COM mandates re-entrency for STA hosted objects.
Exactly. That's exactly what happens. That's why if creating COM objects
in STA thread and the object has finalizer that calls Release, don't call
WaitForPandingFinalizers
Not exactly threre is a timeout.
Bad wording, it wait's a certain amount of time (that's changed in CLR v2).
Well. .NET has enough sync primitives (each of which I believe are based
on OS primitives at the moment)
Yes, but the OS primitives are wrapped by the CLR's synch. primitives. The
CLR is free to do anything he likes, you would be supprised to see what he's
doing before calling into the OS
The bottom line: When the thread is blocked that's it it is blocked,
period. There is no semiblocked threads.
While GC.WaitFor.... and COM object is not easily to verify (fortunately
there is KB article for that) all other sync methods can be tested. Just
run some tests and you'll see there is no pumping.
Just run the native debugger, and see there is pumping
