views:

311

answers:

1

According to this article if I register my COM object with either "Both" or "Free" threading model that object must be completely thread-safe. Specifically all accesses to global shared variables must be synchronized and all accesses to member variables must also be synchronized. That's a lot of effort.

Now I understand that being able to register my object as using "Free" threading model is advantageous and might be worth paying the price of making it completely thread-safe. But why would I want to do all the same and register my object using "Both" threading model instead? What would be the advantage? How do I choose between "Both" and "Free"?

+3  A: 

The main reason for marking your component as supporting threading model "Both" is for performance improvements when the component is being called from a Single Threaded Apartment (STA).

If you mark your component as MTA and your component is created from within a STA then your component will be created in a separate MTA apartment and the "resultant inter-apartment marshaling might degrade performance enough to negate all the work put into making an efficient, free-threaded component". However, if your component's threading model is marked as "Both" then it will be created inside the apartment of the STA object and accessed directly.

So if you think your component may be called from within a STA (all VB6 COM objects are STA) you might want to mark the threading model as "Both".

A good KB article on OLE Threading Models.

Update

You might want to use a "Free" thread model if your component uses other components that are marked as "Free". If your component was marked as "Both" then there could be excessive apartment switching between the "Both" component running in the STA and the MTA. As a general rule, try to create the component as close to the caller as possible (i.e. same apartment) while functioning properly under all scenarios.

Another situation that would warrant marking your component as "Free" is if it explicitly blocks (e.g. Thread.Sleep). If the component is marked as "Both" and instantiated in a STA then the Free component would block the STA message pump.

If you are planning on using the component in IIS, then there are other things to consider. For IIS, "Both" is the recommended setting. Mainly to avoid locking issues with Apartment threaded components, performant access to COM+ ObjectContext and the fact that "Free" threaded components use the system security context (if you require access to the user's security context). See Selecting a Threading Model for Components in IIS for more info about IIS threading considerations.

Other things to consider are COM+ support and how your components behave if they are run in COM+ and whether interface pointers are passed and stored.

Is it any wonder we moved to .NET? :)

An excellent article is COM Threading and Application Architecture in COM+ Applications. It has a COM+ focus but also discusses COM. For your question, read the section entitled "Threading Model Recommendations". It (almost) goes without saying that anything by Don Box is always enlightening.

Tuzo
That's great explanation except I now don't get why I would mark my object being "Free" and not "Both" since looks like "Both" is more advantageous.
sharptooth
Because you might want to "force" it in the MTA i.e. it will be accessed by lots of other objects in the MTA and you don't want these to use proxies to the STA your object is created on (by a VB6 consumer)
wqw
Well, if there're two threads - one STA and one MTA and both call CoCreateInstance() then... If an object is marked as "Both" one copy is created in STA and one in MTA. The calls from Thread1 to STA and from Thread2 to MTA are direct, others pass through proxies. If the obejct is marked as "Free" both copies are in one MTA and only only calls from Thread1 to MTA pass through proxy, other calls are direct. That's all cool, but why would the object enforce the latter and not let it be clients' problem?
sharptooth
I guess this is why they introduced "Neutral"...
sharptooth

related questions