I did some VERY basic COM programming in C and C++ in 1999. It was so basic it really was just a few function calls exposed so that they could be called from Visual Basic. I initially struggled with Variant. Then I learned to love the elegance of the giant union. I hated that there were so many type of strings. I had done MFC, but this was ATL. And of course I was wrapping up ONC (yes not DCE!) RPC calls, so I eventually wanted char*. Long story short, I learned a little bit about COM, and I never used it again. I remember through the process, reading about COM threading models and the single apartment model and the multi apartment model. Of course usually these topics just got in the way of what I wanted, which was the simple VB-> C -> ONC RPC-> network cloud -> omg calling function on unix, which I wanted.
(I still love that concept. It was pretty easy to call unix from windows or windows from unix, using ONC RPC. Yes, ONC RPC can be a pain, but it works. I don’t recall where I found my ONC RPC toolkit for win32, and yes it was very much a kludge.)
Here I am years later, and I actually found that Threading model stuff useful!
After reading a series of news group posts…
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/7ee0a48dde3d4188/bf6f1ac9c25190ad?q=QueryInterface+for+interface++failed.+service+permissions+-outlook&rnum=10&hl=en
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/8c313072acb7b8f4/673e7d3c744e452f?q=QueryInterface+++failed&rnum=1&hl=en
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.windowsforms/browse_thread/thread/e40283466a8688c8/f4febade7679f67f?q=stathread&rnum=2&hl=en
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/df6b006cb3bcfaf9/1d204a540064f9a4?q=QueryInterface+++failed+sta&rnum=1&hl=en
I finally realized that, HEY! Maybe that AspExec legacy COM control, that I don’t think we should be using anyway, is expecting an STA model. Even though my VB.NET Windows Service is marked with the STAThread attribute, when I spawn new threads by creating new System.Threading.Thread objects, I should set the ApartmentState property to STA.
The AspExec control expects to be run from legacy ASP. Legacy ASP uses the STA model. ASP.NET can be told to use the STA model by setting ASPCompat attribute of the @Page directive to true. That part is well documented. I have a feeling that if the ASP.NET page or webservice were creating instances of Thread, that those instances would need their ApartmentState property set to STA as well. Spawning threads in ASP.NET Pages or WebServices is probably not very common or even advised.
I was tickled pink when it turned out that this was the issue. All those years ago I had studied COM and thought I would never need that thread model information, but it turns out I used it after all.