What are the limitations of a STA thread in compare to MTA threads?
Asked Answered
S

2

17

If we make a thread STA like this: Thread.SetApartmentState(STA); then it cannot run code marked with [MTAThread] attribute.

We have seen [STAThread] in windows and console applications but I have never seen code with [MTAThread] attribute and don't know which .NET libraries use this attribute.

My question is what are the limitations of a thread with apartment state set to STA, in compare to threads with MTA apartment state (natural .NET threads) ?

Suit answered 25/12, 2010 at 11:1 Comment(0)
C
18

then it cannot run code marked with [MTAThread] attribute.

That's not how it works. The apartment type is a property of a thread, not of a method. You see the [STAThread] attribute applied only to the Main() method of a .NET program. It determines the apartment type of the very first thread that is created to run the program. Necessary because you can't call SetApartmentState() after the thread is running. Beyond that, the attribute has no meaning, the thread stays in an STA for its lifetime. You never see [MTAThread] because that's the default.

A thread that's STA has some limitations. It can never block because that will block and often deadlock any code that tries to call a method of an apartment threaded COM object. And it must pump a message loop so that COM can marshal the method call from another thread. Marshaled method calls can only be executed when a thread is 'idle', not busy executing any code. A message loop provides that 'not busy' state.

There are requirements on the COM component as well. It must support marshaling, either by restricting itself to the subset of types that are supported by Automation so that the standard marshaller can be used. Or by providing a proxy/stub pair for custom marshaling. The HKCR\Interface\{iid}\ProxyStubClsid32 registry key determines how the marshaling is done.

Sharing an apartment threaded object between an STA and an MTA thread is explicitly supported. The STA thread must create it, any calls on the MTA thread (or other STA threads) is marshaled. Which ensures that the component only ever sees calls made on the same thread, thus ensuring thread-safety. No additional locking is required.

Last but not least, if you create an apartment threaded COM object on an MTA thread then COM will automatically create an STA thread to give it a safe home. The only failure mode for this is when the COM component doesn't support marshaling. The one disadvantage of doing it this way is that every call will be marshaled. That's slow.

Claudette answered 25/12, 2010 at 16:24 Comment(2)
MTAThread is only default in c#. In vb.net STAThread is the default. Just saying...because this took me quite some time to find outPanhellenic
That's accurate for a VB.NET console mode project. Gross violation of the STA requirements btw, an STA thread must pump. VB programmers never have much luck writing threaded code, the default instance of a Form class is another major trap. Maybe that was all on purpose :)Claudette
A
0

I don't think it makes any difference if you don't use COM. If you do, then in some instances, COM objects may be only accessible from only one or another type of thread. If the COM object works in both apartments, then try doing performance tests. Or read about COM apartments on MSDN. But I don't think it matters for performance, it's rather a design choice or something.

Attemper answered 25/12, 2010 at 11:12 Comment(1)
I use some COM components and need STA. Changing apartment state do what I need. I'm not sure about the consequences. One STA thread and one MTA thread share an object inside an ASP.NET application.Suit

© 2022 - 2025 — McMap. All rights reserved.