105

From the MSDN article on STAThread:

Indicates that the COM threading model for an application is single-threaded apartment (STA).

(For reference, that's the entire article.)

Single-threaded apartment... OK, that went over my head. Also, I read somewhere that unless your application uses COM interop, this attribute actually does nothing at all. So what exactly does it do, and how does it affect multithreaded applications? Should multithreaded applications (which includes anything from anyone using Timers to asynchronous method calls, not just threadpools and the like) use MTAThread, even if it's 'just to be safe'? What does STAThread and MTAThread actually do?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222

3 Answers3

63

Apartment threading is a COM concept; if you're not using COM, and none of the APIs you call use COM "under the covers", then you don't need to worry about apartments.

If you do need to be aware of apartments, then the details can get a little complicated; a probably-oversimplified version is that COM objects tagged as STA must be run on an STAThread, and COM objects marked MTA must be run on an MTA thread. Using these rules, COM can optimize calls between these different objects, avoiding marshaling where it isn't necessary.

Bruce
  • 8,202
  • 6
  • 37
  • 49
  • 7
    That is oversimplified. Multithreaded objects can run in any thread. Apartment threaded objects can only run in the apartment they were created in. – 1800 INFORMATION Oct 03 '08 at 01:44
  • 28
    A call from an STA object on an STA thread, to an MTA object, will marshal over to an MTA thread (unless the MTA object implements the free-threaded marshaler). Like I said, the details can get complicated. (I worked on the COM team for a number of years *grin*) – Bruce Oct 03 '08 at 02:26
  • 9
    Sometimes you need to be aware of this even if you are not using COM directly. A thread must use the Single-Threaded Apartment model if it displays any graphical windows. This is why [STAThread] is always displayed on top of the main method in a windows forms application. – Justin Ethier May 15 '09 at 13:43
  • 6
    Couldn't something like a Font or File dialog use COM without you knowing? I would assume they do internally, wouldn't that mean that almost any Windows Forms application would require STAThread to be set? Forgive my naieve assumption as I've not actually done COM programming. – Brett Ryan Feb 05 '10 at 17:05
  • 4
    A more detailed answer for those that are interested: http://stackoverflow.com/questions/4154429/apartmentstate-for-dummies – jgauffin Jan 12 '11 at 11:53
  • But you should remember and work in STA, when you are programming UI in winforms. Even if you don't use COM. – Alex Blokha Mar 13 '12 at 18:33
  • 2
    Sorry for resurrecting an old comment chain but @BrettRyan raises a very valid point here. I actually found this thread because if you use a file selection dialogue in winforms without marking Main() as STAThread, it will die. I can also (thank God) confirm that it didnt affect any of the several background workers I have in my program, presumably because they dont make any COM calls to my knowledge. – Josh Bibb Nov 14 '12 at 15:26
  • @BrettRyan - the file open dialog should not be based on COM. However there are a variety of active x controls which rely on the creating thread to be in an STA. – quixver Dec 18 '14 at 21:51
3

What that does it it ensures that CoInitialize is called specifying COINIT_APARTMENTTHREADED as the parameter. If you do not use any COM components or ActiveX controls it will have no effect on you at all. If you do then it's kind of crucial.

Controls that are apartment threaded are effectively single threaded, calls made to them can only be processed in the apartment that they were created in.

Some more detail from MSDN:

Objects created in a single-threaded apartment (STA) receive method calls only from their apartment's thread, so calls are serialized and arrive only at message-queue boundaries (when the Win32 function PeekMessage or SendMessage is called).

Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. You would typically implement some form of concurrency control in a multithreaded object's code using Win32 synchronization primitives such as critical sections, semaphores, or mutexes to help protect the object's data.

When an object that is configured to run in the neutral threaded apartment (NTA) is called by a thread that is in either an STA or the MTA, that thread transfers to the NTA. If this thread subsequently calls CoInitializeEx, the call fails and returns RPC_E_CHANGED_MODE.

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
  • The MSDN article is helpful from a COM perspective but can you tell me when .NET calls `CoInitialize()` in response to the `STAThread` attribute / `ApartmentState`? Note: The article on MSDN is here: [CoInitializeEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms695279%28v=vs.85%29.aspx). – jrh May 04 '17 at 14:48
  • Does [thread->SetApartment](https://github.com/dotnet/coreclr/blob/master/src/vm/comsynchronizable.cpp#L987) use `CoInitialize()` internally? I traced the STAThread Attribute all the way down there but the trail has gone cold (I can't find the source for `Thread::SetApartment`). Is the Thread class from thread.h (the COM thread.h) documented anywhere? Is it MFC, ATL, or something else? – jrh May 05 '17 at 19:18
  • @jrh I don't know any more details than that sorry – 1800 INFORMATION May 05 '17 at 19:21
-15

STAThread is written before the Main function of a C# GUI Project. It does nothing but allows the program to create a single thread.

Zeinth
  • 25
  • 1