No offense, but this is not correct.  

STA does not mean "only one thread".  An application can have numerous STA
threads.  STA means that only one thread is used to execute through
objects/code that are in the "apartment" AND that the thread WILL/MUST pump
messages (i.e. it can NOT block).  STA is necessary for direct access (or
rather to have any chance of) to "apartment" threaded objects.  It's also
necessary if you create windows using that thread.  For example, the main
thread of a WinForm app...  

When you call out of an STA, the COM infrastructure continues to pump
messages to keep your UI responsive.  If it did not, you're window(s) would
not repaint and you could get into a deadlock situation rather easily.  Of
course that introduces reentrancy into the STA too, but that's another
topic...

So bottom line is you can't *block* an STA thread because STA threads are
required to process messages.  And you can't change a WinForm thread to MTA.
However, you CAN spawn new threads in a WinForm App that do not directly
create or manipulate WinForm elements and make THOSE threads MTA threads (or
don't set MTA or STA if you don't use COM directly or indirectly on that
thread).

IIRC, you will need to pinvoke MsgWaitForMultipleObjectsEx to properly sync
your STA/WinForm thread.  

Russ

-----Original Message-----
From: Unmoderated discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED] On Behalf Of Peter Ritchie
Sent: Friday, September 23, 2005 6:42 AM
To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-DOTNET] WaitHandle.WaitAll STA thread.


Of course you can change STAThread to MTAThread.  If you make use of any
free-threaded COM objects you would have to change STAThread to MTAThread
that anyway.  If you use the ThreadPool you'd probably also want to switch
to a multi-threaded apartment.

STAThread is documented as only affecting COM interop interactions.  This is
obviously not true, it also affects (at least) WaitHandle.WaitAll ().  .NET
applications default to STAThread as a least-privileges principle, as you
(normally) manually start multiple threads.  I guess you're magically
supposed to know the importance of MTAThread when you spawn extra threads or
use WaitAll().  If you're not spawning any extra threads MTAThread will only
affect WaitAll() and COM interactions.

To ensure you cannot get any external calls to your assembly via COM you can
add the COMVisible(false) attribute to your assembly, which I believe what
FxCop suggests by default.

If you're not using COM (you can ignore the rest of this, in that case),
using MTAThread will not affect how you must design your application to deal
with synchronization during incoming calls to your apartment via your COM
interface, other than typical threading synchronization issues.  With a
multi-threaded apartment COM calls from outside or to outside the apartment
are still blocking, calls between COM objects *within* the multi- threaded
apartment are not blocking and not marshaled--which is where the extra
synchronization comes in.  If you created a single-threaded apartment within
your process, it too would have all incoming calls marshaled and blocked,
even if they came from the multi-threaded apartment.

If you make your assembly or any of it's methods COMVisible, or start
creating new apartments within your process, or give any COM interfaces to a
free-threaded apartment; you'll have to revisit synchronization design of
your application.

http://www.peterRitchie.com/

On Fri, 23 Sep 2005 08:55:58 -0400, Allan N. <[EMAIL PROTECTED]> wrote:

>Hi Peter,
>are you telling me I can simply change my sta to mta on my Winform ?
>
>I was under the impression that this was a no no....
>
>cheers Allan
>
>On Fri, 23 Sep 2005 08:48:42 -0400, Peter Ritchie 
><[EMAIL PROTECTED]> wrote:
>
>>For specific check out: 
>>http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx
>>
>>For what it's worth, when I changed STAThread to MTAThread WaitAll 
>>worked fine, as expected.
>>
>>http://www.peterRitchie/
>>
>>On Fri, 23 Sep 2005 05:28:28 -0400, Allan N. <[EMAIL PROTECTED]> wrote:
>>
>>>Hi,
>>>in my naive attempt to spin off 6 threads and then wait for them to
>finish
>>>before filling a grid I got the
>>>"WaitAll for multiple handles on an STA thread is not supported" 
>>>message flashing in my eyes.
>>>
>>>checking the documentation was perhaps the best I could have done 
>>>before going this way :).
>>>
>>>what else could I use here instead of WaitAll ? using 
>>>ManualResetEvent [curThread].WaitOne and then looping seems rather 
>>>tedious...

===================================
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