Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why could COM interop layer be 40 times slower when client is compiled in VS 2010 vs VS 2005?

It was kind of a long shot. Glad I could help.

Matching MTA vs STA (threading model) is really important when making lots of distinct calls into any COM object. An [STAThread] directive at the top of a method is one way to be sure of threading model for every call in that method.

Looks like Thread.SetApartmentState(ApartmentState.STA) will work for a whole thread, but not apparently for thread pool threads.


When you say, "...even in an STA application threads are...", that isn't actually correct. A thread can choose to set up it's apartment state before it accesses any COM objects, but in .NET if you do nothing those threads will implicitly be MTA.

The threadpool is MTA. It will need to be if you think about it, because if it were full of STA threads it would be a crappy thread-pool as any time a thread tried to access an object created on one of the other threads in the pool it would require marshalling.

Thread.SetApartmentState will only work per thread by definition. It could never affect any other threads (as you've discovered). Objects belong to an apartment and a thread may belong to a single threading model. If the thread tries to visit an object with a mismatched model it will need to be marshalled.

If your COM Server is marked as "both" then you can use it without a proxy from either an STA or an MTA thread. If that's the case, you're lucky, and you should create it on an MTA thread to begin with (or have the threadpool threads do so).

If you create it on an STA thread, even if (especially if) all your other threads are STAs, they will ALL go through a proxy, unless you happen to call the object from the thread that originally created it.

If your COM server is single threaded then you'll need to make sure you call it not only from an STA thread, but the STA thread that first creates it, otherwise you'll be marshalled through a proxy.