Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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) ?

like image 711
Xaqron Avatar asked Dec 25 '10 11:12

Xaqron


People also ask

What is STA and MTA threading model?

STA means that your COM-object must be always manipulated on the UI thread and cannot be passed to other threads (much like any UI element in MFC). However, your program can still have many threads. MTA - You can manipulate the COM object on any thread in your program.

What is an Stathread?

STAThreadAttribute indicates that the COM threading model for the application is single-threaded apartment. This attribute must be present on the entry point of any application that uses Windows Forms; if it is omitted, the Windows components might not work correctly.


1 Answers

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.

like image 198
Hans Passant Avatar answered Oct 16 '22 04:10

Hans Passant