For some reason, a bunch of COM related stuff's been coming onto my radar lately, so for some reason, I've been dealing with a lot of COM related issues. Go figure this one out.
The other day, I received a message from a co-worker asking me (roughly) "I have an apartment threaded COM component. Does this mean that I can't use threads in the object?"
It's a really good question, and I had to think about it for a while before answering.
CAVEAT: I'm not a COM person, so it's possible the answer is more complicated than this, but here goes.
The simple answer is that by declaring your component as being apartment threading is an indicator to the CREATOR of your object that it's only safe to call the methods on your object from the thread that initially created the object. The contract says NOTHING about how you internally implement your component. So you are free to use whatever internal mechanisms you want in your component.
However, as always, there is a huge caveat.
By declaring your COM object as apartment threaded, you've told COM that the methods on the interfaces to your object can only be called from the thread that created the object. That means that if COM ever drops one of the standard marshallers between your other threads and the interfaces (which shouldn't happen, but might in some COM interop scenarios, or if you're subclassing the standard marshaller, or if your COM object is an inproc handler), then COM's going to enforce the threading model you declared for your object. Which means that COM might start returning RPC_E_WRONGTHREAD to your method calls if they go through the marshaller.
The thing is that you might get away with this for years (since none of the COM marshallers will be involved in most in-proc scenarios), until some point in the future when your component is called in a scenario you don't expect and all of a sudden, the COM marshaller gets in the way and all of a sudden things stop working.