Thread Apartment States

Published August 22, 2009
Advertisement
Most anyone who's written a windows application in .NET has seen the funny [STAThread] attribute adorning their Main function. The more curious of these folks have done a little digging and found that it has to do with "Advanced COM Magic" and left it at that. Others, not satisfied with magical explanations, have dug still deeper and found that it has to do with COM, and the two different, mutually exclusive ways it handles threading.

For the uninformed, COM objects can be accessed in two different ways: single threaded apartment and multithreaded apartment. Many components are designed to work in only one mode or the other, such as several Winforms GUI components. Because of this, the default program generated by Visual Studio attaches the [STAThread] attribute to tell the runtime to initialize the main thread as using single threaded apartment mode.

So far, so good. I'm writing a bit of managed glue code in C++/CLI that uses a COM component that requires single threaded apartment mode to run correctly. I check to make sure that my test application has the appropriate thread set, and then run my first test, with good results. Awash with the euphoria of victory, I walk away to go eat a brownie.

When I return, I make a few adjustments to my DLL, and run the test app again. Lo and behold, I fail with a cryptic HRESULT return code from CoCreateInstance, which is in charge of creating the necessary COM component. Frowning, I rollback my changes and try again. Still no good. This makes no sense, right?

After a lot of digging, I do a little test. I insert the following code right before CoCreateInstance:
ApartmentState state = Thread::CurrentThread->GetApartmentState();


I put a breakpoint there and run the debugger. Sure enough, the apartment state for thread is set to MTA (multithreaded apartment). That's odd. I'm sure it's set to STA. I check back to my Main method to be sure. Yep, it's still got the attribute on there. I insert my debugging code as the first line of Main. You can see the hilariousness for yourself here:


So apparently, the CLR is ignoring my STAThread attribute and initializing the main thread as multithreaded. Not very considerate if you ask me. On an off chance, I try running my application without the debugger. Success! We now have an STA thread. I try a few other configurations, each with mixed results.

I did a little Googling, and while there is some confirmation of this peculiar behavior, there was little on how to actually fix it. I fought with it for a bit before giving in and adding the following lines before the creation of the COM component:
if (Thread::CurrentThread->GetApartmentState() != ApartmentState::STA){    CoUninitialize();    CoInitialize(NULL);}


Compile and run without issues! It's a little heavy handed I'll admit, but I'm not really sure what else to do. Has anyone else ever experienced this behavior? It's really quite bizarre. Leave a comment below to let me know what you think!
Previous Entry GDNet+
Next Entry I'm all growed up
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement

Latest Entries

New Blog

1998 views

Progress Update

1544 views

Start of Project

1511 views

New Job

2193 views

The Downward Spiral

2851 views

Job Interviews

1456 views
Advertisement