The
neutral
threaded
apartment (NTA) is a new threading model
available only on Windows 2000. Although it is not specific to COM+
(classic COM objects can also take advantage of the NTA), the NTA is
the recommended threading model for most COM+ objects that do not
have a user interface.
The NTA has evolved to address a deficiency in the classic COM
MTA threading model: suppose you have an
STA client accessing an MTA object. Under
classic COM, all cross-apartment calls have to be marshaled via a
proxy/stub pair. Even though the object could have handled the call
on the client STA thread, the call is marshaled. The stub performed
an expensive thread context switch to an RPC thread to access the MTA
objects.
There was clearly a need for an apartment that every thread in the
process could enter without paying a heavy performance penalty. This
is what the NTA is: an apartment that every COM-aware thread can
enter. In every process, there is exactly one NTA. The NTA is
subdivided (like any other apartment) into contexts. COM objects that
reside in the NTA set their threading model value in the Registry to
Neutral
.
Much like an MTA object, an object marked as neutral will reside in the NTA, regardless of its creator’s apartment. Calls into the NTA are marshaled, but only light-weight proxies are used (to do cross COM+ context marshaling, if needed) because no thread-context switch is involved. A method call on an NTA object is executed on the caller’s thread, be it STA or MTA based.
No thread calls the NTA home, and the NTA contains no threads, only
objects. Threads can’t call CoInitializeEx( )
with a flag saying NTA, and no such flag exists. When you
create a thread, you still must assign it to an STA of its own or to
the MTA.
When you mark your object as
Neutral
, it will always reside in the NTA,
regardless of the location of its creating client. When you mark your
object as Both
, if the object’s creator is
an NTA object, the object will reside in the NTA as well. If your NTA
object creates other objects marked as Apartment
,
the location of the creating thread may affects where those objects
reside. Table 5-3 presents the potential results
when NTA clients create other objects. It also shows the resulting
object apartment, based on the object threading model and the thread
the NTA client runs on. You can also see from Table 5-3 that components marked as
Neutral
will always be in the NTA, regardless of
the apartment of their creator.
Table 5-3. Apartment activation policy
Object isClient is: |
Apartment |
Free |
Both |
Neutral |
Not specified |
---|---|---|---|---|---|
STA, not main |
Current STA |
MTA |
Current STA |
NTA |
Main STA |
Main STA |
Main STA |
MTA |
Main STA |
NTA |
Main STA |
MTA |
Host STA |
MTA |
MTA |
NTA |
Main STA |
Neutral (on STA thread) |
On that STA thread |
MTA |
NTA |
NTA |
Main STA |
Neutral (on MTA thread) |
Host STA |
MTA |
NTA |
NTA |
Main STA |
The NTA model obeys the COM rule specifying that all objects must be marshaled outside the apartment/context boundary, just like any other apartment. If you have to manually marshal an object outside the NTA, use the Global Interface Table (the GIT) or the GIT wrapper class, presented in Chapter 2.
Finally, the NTA offers improved DCOM performance because incoming calls from remote machines to NTA objects can execute directly on the thread that handles the incoming remote call, without a thread context switch.
Your
COM+ component should run in the STA if
any one of the following statements is valid:
Your COM+ component displays a user interface or it relies on having a message loop pump messages to it. Your component relies on the STA thread message pump.
Your COM+ component uses Thread Local Storage (TLS), a thread-specific heap allocated off the thread stack. It must run in the STA because TLS relies on having the thread affinity the STA provides.
Your component was provided by a third party as a COM component and
marked as Apartment
. You want to import it to your
COM+ application so that it shares your application settings, such as
security and process, and is part of your application’s MSI
file. You should not change the threading model, because you do not
know how much thread affinity the component requires.
Your component is developed using Visual Basic 6.0.
Your COM+ component should use the Both
threading
model if the creating client is in the STA or MTA, but not the NTA;
it makes very frequent method calls; and the calls have short
duration. By using Both
, you will avoid
cross-apartment marshaling, an overhead that may hinder performance
under this scenario.
In all other cases, your COM+ component should use the
Neutral
threading model. You will need to use
activity-based synchronization to provide synchronization to your
component.
You should avoid using the Free
threading model
for your component because running in the NTA will offer the same
throughput without the additional thread context switch involved with
calls into the MTA. Only legacy components imported into COM+ should
use Free
as
the
threading
model.