PC Review
Forums
Newsgroups
Microsoft DotNet
Microsoft C# .NET
difference between STA and MTA
Forums
Newsgroups
Microsoft DotNet
Microsoft C# .NET
difference between STA and MTA
![]() |
difference between STA and MTA |
|
|
Thread Tools |
Rating:
|
|
|
#1 |
|
Guest
Posts: n/a
|
hi
i read thousands of millions of articles about STA and MTA :-). everything very theoretical and i don't get it... could anybody explain me the [STAThread] and [MTAThread] on a nice, small and simple example where i really can see the difference between these two methods... they're all talking about 2 message loops and com interop... but what benefit does i get when using either STA or MTA? thanx, jazper |
|
|
|
#2 |
|
Guest
Posts: n/a
|
Wow thousands of millions is alot of articles ;-)
The reason articles refer to COM interop when they talk about STAThread and MTAThread is because those attributes only have any relevance when you are performing COM interop. They have no impact whatsoever when no COM interop occurs. So do you understand STAs and MTA in COM terms? Regards Richard Blewett - DevelopMentor http://www.dotnetconsult.co.uk/weblog http://www.dotnetconsult.co.uk hi i read thousands of millions of articles about STA and MTA :-). everything very theoretical and i don't get it... could anybody explain me the [STAThread] and [MTAThread] on a nice, small and simple example where i really can see the difference between these two methods... they're all talking about 2 message loops and com interop... but what benefit does i get when using either STA or MTA? thanx, jazper |
|
|
|
#3 |
|
Guest
Posts: n/a
|
As Richard said, STA's and MTA's are artifacts of COM.
In the early days of 16 bit Windows there was only one thread in all of the operating system, so no one developing COM-objects then needed to worry about if their code was called from multiple threads. No one needed synchronization objects such as events and mutexes. Good times all around ![]() When Win32 came along you suddenly found yourself with all these threads that could potentially call into your nice piece of code that was only designed to be called from one and only one thread. What to do? There had been a lot of COM-objects developed for 16-bit Windows that was used in thousands of millions of applications ( ) and it was not feasible tojust throw them away because we now finally could do multitasking. The solution was apartments. COM applications in 16-bit Windows already had to perform some initialization prior to begin using COM, they had to call the method CoInitialize(). So here was a way to identify COM-applications that don't know anything about threading. If you call CoInitialize you don't know what threads are and if you have created an object on a thread, you assume that all calls to that object come in on the same thread. Cool! The requirement that you need to initialize COM before you could use any of it was kept, but now you had to perform that initialization on every thread that was about to use or create a COM object. Those applications that was designed with threading in mind could state that by calling a new method, CoInitializeEx, and state if they allowed calls coming in from any thread or from just the one thread. Any thread that calls CoInitialize() is said to enter the Single Threaded Apartment (STA). In that apartment there can live only one thread. If someone calls an object that is created on a thread in an STA from another thread, the COM-runtime is said to marshal the code from one thread to the other. This is accomplished by posting windows messages to the STA thread. Windows messages will be put in the threads message queue, which gives the thread a chance to handle them nice and easy one by one. This is why a thread in an STA must contain a message pump. A thread can call CoInitializeEx and state that the code here can handle calls from multiple threads, that it has all the mutexes and critical sections or whatever in check. These threads are said to enter the Multi Threaded Apartment. An object created by a thread in the MTA can be called directly by code on any other thread that is also in the MTA. No marshalling and windows messaging voodoo necessary. Pheew! So when a .NET application is about to call a COM-object via interop, it checks the current threads apartment state, which can either be MTA, STA, or unknown. If the threads apartment state is STA, CoInitialize() is called before interop is performed. If MTA or Unknown is set, CoInitializeEx() is called with the multithreaded parameter. This enables the COM-runtime to use marshalling where needed and skip it where it is not needed. The thread's apartment state can be set by using the Threading.ApartmentState property for any thread or by applying the STAThread or MTAThread to the application's Main method. Jeeesh, what a long post! There are a lot more details to it, but I think this covers the basics. Regards, Joakim Richard Blewett [DevelopMentor] wrote: > Wow thousands of millions is alot of articles ;-) > > The reason articles refer to COM interop when they talk about STAThread and MTAThread is because those attributes only have any relevance when you are performing COM interop. They have no impact whatsoever when no COM interop occurs. > > So do you understand STAs and MTA in COM terms? > > Regards > > Richard Blewett - DevelopMentor > http://www.dotnetconsult.co.uk/weblog > http://www.dotnetconsult.co.uk > > hi > > i read thousands of millions of articles about STA and MTA :-). everything > very theoretical and i don't get it... > could anybody explain me the [STAThread] and [MTAThread] on a nice, small > and simple example where i really can see the difference between these two > methods... > > they're all talking about 2 message loops and com interop... but what > benefit does i get when using either STA or MTA? > > thanx, jazper > > |
|
|
|
#4 |
|
Guest
Posts: n/a
|
A few mistakes....
There's never been a version of COM for 16 bit windows. So there have never been 16 bit applications based on COM. Willy. "Joakim Karlsson" <jkarlsson@NOSPAMjkarlsson.com> wrote in message news:OFKyAMb%23EHA.3708@TK2MSFTNGP14.phx.gbl... > As Richard said, STA's and MTA's are artifacts of COM. > > In the early days of 16 bit Windows there was only one thread in all of > the operating system, so no one developing COM-objects then needed to > worry about if their code was called from multiple threads. No one needed > synchronization objects such as events and mutexes. Good times all around > ![]() > > When Win32 came along you suddenly found yourself with all these threads > that could potentially call into your nice piece of code that was only > designed to be called from one and only one thread. What to do? There had > been a lot of COM-objects developed for 16-bit Windows that was used in > thousands of millions of applications ( ) and it was not feasible to just> throw them away because we now finally could do multitasking. > > The solution was apartments. COM applications in 16-bit Windows already > had to perform some initialization prior to begin using COM, they had to > call the method CoInitialize(). So here was a way to identify > COM-applications that don't know anything about threading. If you call > CoInitialize you don't know what threads are and if you have created an > object on a thread, you assume that all calls to that object come in on > the same thread. Cool! > > The requirement that you need to initialize COM before you could use any > of it was kept, but now you had to perform that initialization on every > thread that was about to use or create a COM object. Those applications > that was designed with threading in mind could state that by calling a new > method, CoInitializeEx, and state if they allowed calls coming in from any > thread or from just the one thread. > > Any thread that calls CoInitialize() is said to enter the Single Threaded > Apartment (STA). In that apartment there can live only one thread. If > someone calls an object that is created on a thread in an STA from another > thread, the COM-runtime is said to marshal the code from one thread to the > other. This is accomplished by posting windows messages to the STA thread. > Windows messages will be put in the threads message queue, which gives the > thread a chance to handle them nice and easy one by one. This is why a > thread in an STA must contain a message pump. > > A thread can call CoInitializeEx and state that the code here can handle > calls from multiple threads, that it has all the mutexes and critical > sections or whatever in check. These threads are said to enter the Multi > Threaded Apartment. An object created by a thread in the MTA can be called > directly by code on any other thread that is also in the MTA. No > marshalling and windows messaging voodoo necessary. > > Pheew! > > So when a .NET application is about to call a COM-object via interop, it > checks the current threads apartment state, which can either be MTA, STA, > or unknown. If the threads apartment state is STA, CoInitialize() is > called before interop is performed. If MTA or Unknown is set, > CoInitializeEx() is called with the multithreaded parameter. This enables > the COM-runtime to use marshalling where needed and skip it where it is > not needed. > > The thread's apartment state can be set by using the > Threading.ApartmentState property for any thread or by applying the > STAThread or MTAThread to the application's Main method. > > Jeeesh, what a long post! There are a lot more details to it, but I think > this covers the basics. > > Regards, > Joakim > > > Richard Blewett [DevelopMentor] wrote: >> Wow thousands of millions is alot of articles ;-) >> >> The reason articles refer to COM interop when they talk about STAThread >> and MTAThread is because those attributes only have any relevance when >> you are performing COM interop. They have no impact whatsoever when no >> COM interop occurs. >> >> So do you understand STAs and MTA in COM terms? >> >> Regards >> >> Richard Blewett - DevelopMentor >> http://www.dotnetconsult.co.uk/weblog >> http://www.dotnetconsult.co.uk >> >> hi >> i read thousands of millions of articles about STA and MTA :-). >> everything >> very theoretical and i don't get it... >> could anybody explain me the [STAThread] and [MTAThread] on a nice, >> small >> and simple example where i really can see the difference between these >> two >> methods... >> they're all talking about 2 message loops and com interop... but what >> benefit does i get when using either STA or MTA? >> thanx, jazper >> |
|
|
|
#5 |
|
Guest
Posts: n/a
|
So the crucial thing is which apartment type should you choose for your code.
If you are doing Windows Forms programming *always* mark the main thread with the STAThread attribute. Some controls are wrappers around ActiveX controls and so COM interop with be being used. ActiveX controls are all STA based and IIRC don't support being hosted from an MTA thread. Any other project you can omit the attribute unless it performs COM interop where you should really take control of your thread's apartment state. You want to make sure the thread enters the same typoe of apartment as the COMM object it is calling. There is a 1000 fold performance penalty for calling cross apartment compared with intra apartment calls Regards Richard Blewett - DevelopMentor http://www.dotnetconsult.co.uk/weblog http://www.dotnetconsult.co.uk As Richard said, STA's and MTA's are artifacts of COM. <snip: Joakim's excellent description of apartments omitted from brevity> |
|
|
|
#6 |
|
Guest
Posts: n/a
|
Actually there was a 16 bit version of COM - is was mostly a bit of an oddity but it did exist (you can dig out various articles from the 90s that mention it).
Regards Richard Blewett - DevelopMentor http://ww.dotnetconsult.co.uk/weblog http://ww.dotnetconsult.co.uk A few mistakes.... There's never been a version of COM for 16 bit windows. So there have never been 16 bit applications based on COM. Willy. |
|
|
|
#7 |
|
Guest
Posts: n/a
|
OLE1 (and IIRC 16-bit OLE2) was around for 16-bit Windows. OLE1 actually
used DDE for it's communication if memory serves me. But you are correct, I did take a few liberties in my post. What I wanted to do was set the stage for why the STAThread and MTAThread are there. There are much better articles and books if one wants to get in to the details. Regards, Joakim Willy Denoyette [MVP] wrote: > A few mistakes.... > There's never been a version of COM for 16 bit windows. So there have never > been 16 bit applications based on COM. > > Willy. |
|
|
|
#8 |
|
Guest
Posts: n/a
|
hi joakim
wow, thats a large post... thank you for your answer. you said: > Any thread that calls CoInitialize() is said to enter the Single > Threaded Apartment (STA). In that apartment there can live only one > thread. If someone calls an object that is created on a thread in an STA > from another thread, the COM-runtime is said to marshal the code from > one thread to the other. This is accomplished by posting windows > messages to the STA thread. Windows messages will be put in the threads > message queue, which gives the thread a chance to handle them nice and > easy one by one. This is why a thread in an STA must contain a message pump. > A thread can call CoInitializeEx and state that the code here can handle > calls from multiple threads, that it has all the mutexes and critical > sections or whatever in check. These threads are said to enter the Multi > Threaded Apartment. An object created by a thread in the MTA can be > called directly by code on any other thread that is also in the MTA. No > marshalling and windows messaging voodoo necessary. hmmm... i'm thinking..... hmmm... i didn't get all. sometimes i think my brain is just a few sizes too small to get that. ![]() you (or MS) said that apps which calls CoInitialize() are some kind of "marked" as STA. however i can call the CreateThread() API and creates new threads in my c++ app wheater i call CoInitialize() or CoInitializeEx() or just nothing... i wrote a c++ example... maybe when i understand it there, i'll understand it in c# :-) i uses CoInitialize() so my app will be STA right? however i create some threads and start them. inside the threads i can use Semaphore or Mutex (named or unnamed) to synch them. so why is my app STA? i created several threads in it... it must by multithreaded and uses com...? --- CODE ---------------- void threadfunc() { // using Semaphore or Mutex (named or unnamed) to synch the threads //do something like DB query over COM (ado) } void main() { ::CoInitialize(); for(int i=0; i < 10; i++) { DWORD dwThreadId = -1; HANDLE hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, NULL, 0, &dwThreadId); } ::CoUnInitialize(); } |
|
|
|
#9 |
|
Guest
Posts: n/a
|
Jazper Manto wrote:
> hmmm... i'm thinking..... hmmm... i didn't get all. sometimes i think my > brain is just a few sizes too small to get that. ![]() > you (or MS) said that apps which calls CoInitialize() are some kind of > "marked" as STA. however i can call the CreateThread() API and creates new > threads in my c++ app wheater i call CoInitialize() or CoInitializeEx() or > just nothing... The call to CoInitialize(Ex) determines what apartment the calling *thread* will live in. CoI(Ex) does not initialize any application wide settings or anything. In your code snippet the threadFunc method must call CoI(Ex) before it uses any COM objects. The fact that the main thread has called CoIinitialize() just puts the main thread in STA - not the worker thread. And sure, you can create threads all you want without calling CoI(Ex), but as soon you need to use a COM-object you need to have put the thread creating the object in an apartment. > > i wrote a c++ example... maybe when i understand it there, i'll understand > it in c# :-) i uses CoInitialize() so my app will be STA right? however i > create some threads and start them. inside the threads i can use Semaphore > or Mutex (named or unnamed) to synch them. so why is my app STA? i created > several threads in it... it must by multithreaded and uses com...? > Your code should then actually look something like this: void thread() { // Put this thread in a new STA ::CoInitialize(0); // Create and use som COM-objects. ::CoUnitialize(); } void main() { for(int i=0; i < 10; i++) { // Start threads } } Your worker threads has now told the runtime what apartment they should live in. Now, the implementor of the COM-object you are using has declared what kind of threading scenarios it can handle. The COM-object can be declared as 'I must live in an STA' or 'I must live in an MTA' or 'I can live in both'. When your thread wants to create an object the runtime checks what apartment your thread lives in and compares that with the wishes of the COM-object. If the object in question can live in the same type of apartment as your thread, the code in your thread will get a direct pointer to the newly created COM-object. If the apartments between your thread and that of the COM-object mismatch, the code in your thread will receive a pointer to a proxy instead. The proxy is responsible for marshalling your calls to the COM-object. Regards, Joakim |
|
|
|
#10 |
|
Guest
Posts: n/a
|
> In your code snippet the threadFunc method must call CoI(Ex) before it
> uses any COM objects. The fact that the main thread has called > CoIinitialize() just puts the main thread in STA - not the worker thread. aha. so my app can be multithreaded but is marked as STA for com communication?? am i right to say STA and MTA are just some kind of marker only for COM communication. but what benefit will my app get when using ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); or ::CoInitializeEx(NULL, COINIT_MULTITHREADED); - do i have to deal in another way with COM when using MTA instead of STA? - does the behavior in my app changes in some way? - do i have other or even new possibilities using MTA with com? could you mention a concrete example when i would use MTA and when STA with COM... regards, jazper |
|
![]() |
|
| Thread Tools | |
| Rate This Thread | |
|
|

Main Page 



) and it was not feasible to
