PC Review


Reply
Thread Tools Rating: Thread Rating: 2 votes, 5.00 average.

difference between STA and MTA

 
 
Jazper Manto
Guest
Posts: n/a
 
      13th Jan 2005
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


 
Reply With Quote
 
 
 
 
Richard Blewett [DevelopMentor]
Guest
Posts: n/a
 
      13th Jan 2005
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


 
Reply With Quote
 
 
 
 
Joakim Karlsson
Guest
Posts: n/a
 
      13th Jan 2005
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
>
>

 
Reply With Quote
 
Willy Denoyette [MVP]
Guest
Posts: n/a
 
      13th Jan 2005
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" <(E-Mail Removed)> wrote in message
news:OFKyAMb%(E-Mail Removed)...
> 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
>>



 
Reply With Quote
 
Richard Blewett [DevelopMentor]
Guest
Posts: n/a
 
      13th Jan 2005
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>

 
Reply With Quote
 
Richard Blewett [DevelopMentor]
Guest
Posts: n/a
 
      14th Jan 2005
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.

 
Reply With Quote
 
Joakim Karlsson
Guest
Posts: n/a
 
      14th Jan 2005
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.

 
Reply With Quote
 
Jazper Manto
Guest
Posts: n/a
 
      14th Jan 2005
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();
}



 
Reply With Quote
 
Joakim Karlsson
Guest
Posts: n/a
 
      14th Jan 2005
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
 
Reply With Quote
 
Jazper Manto
Guest
Posts: n/a
 
      14th Jan 2005
> 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


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Formless class is MTA rather than STA, how do I make it STA? mike1reynolds Microsoft VB .NET 0 18th Apr 2008 09:07 PM
STA and MTA =?Utf-8?B?VmVua2F0?= Microsoft C# .NET 8 11th Jun 2005 10:55 AM
STA's and MTA's Razzie Microsoft C# .NET 7 26th Oct 2004 03:32 PM
Re: Using STA API in a MTA enviroment =?Utf-8?B?UmF1bA==?= Microsoft ASP .NET 0 17th Sep 2004 03:35 PM
STA vs MTA Ashish Sheth Microsoft Dot NET Framework 2 17th Sep 2004 11:21 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:32 AM.