Do i need to call CoInitialize before interacting with COM in .NET? Do i need to call CoInitialize before interacting with COM in .NET? multithreading multithreading

Do i need to call CoInitialize before interacting with COM in .NET?


The information here isn't actually conflicting - it's just not necessarily super clear if you're new to COM.

Short answer:

  • .Net threads are always already CoInitialized for you - you don't have to (and should not!) call it yourself.
  • ThreadPool threads (and therefore anything that uses ThreadPool threads, like asynchronous delegates and so on) are always initialized MTA. The only option for creating an STA thread is either adding the [STAThread] attribute to Main() to request that the runtime initializes the main thread as STA, or using thread.SetApartmentState(ApartmentState.STA) on a new thread you create before calling thread.Start() - otherwise they are MTA by default. In any case, the thread apartment model cannot be modified once the thread is started and running.

Longer answer: there are two ways to call CoInitialize - you can use it to initialize your thread as a Single-Threaded Apartment thread (STA), or as a Multi-Threaded Apartment thread (MTA). What the text above is saying is that by default, new threads and threadpool threads are automatically pre-CoInitialized as MTA-flavor. But with a new thread, you can use ApartmentState to specifiy STA-flavor, if you do so before actually starting the thread. It's always CoInitialized one way or the other by the time it's started anyhow.

Note that Main() on UI-based programs is marked with the [STAThread] attribute to ensure that it's STA-based; while on a console app, lack of [STAThread] means it's CoInited as MTA. The reason for this attribute, by the way, is that the thread that calls Main() is the one thread you can't specify STA vs MTA using ApartmentState - because it's already running and by the time Main() executes, so too late to use that; so think of the attribute as a hint to the runtime to set the apartment state before Main() is called.

The key thing to be aware of is that STA is usually used with UI and requires a message loop (which .Net WinForms provides for you); STA code should never block with Sleep() or similar, else your UI will also block. MTA, on the other hand, is designed for worker usage - background tasks, downloading files or doing computations in the background, for example, and generally should not own UI. You can use COM from either of these, but it may depend on what the COM object is doing or where you got it from. If it's a UI component, likely you'd want to use it from a STA thread; on the other hand, if it's a component for downloading or doing computations, you'd typically use it from an MTA thread.

Update 1 above is basically saying that the .Net runtime always calls CoInitialize for you - but lets you chose STA vs MTA, with MTA being the default.

Update 2 above is basically saying that since ThreadPool threads are MTA (and you don't get to change that), you should only use them for doing background operations, and not use them for UI tasks.

Update 3 is saying that for new threads, you can chose MTA vs STA - same as update 1, just being more explicit about the APIs.

The whole MTA vs STA thing can get quite complex, suggest reading this article as a starting point. The big picture, though, is mostly summarized by remembering that STA = single thread and UI; MTA = multiple threads, background/worker tasks. (STA vs MTA also applies to objects, not just threads, and COM does a whole bunch of work behind the scenes to let the different types of threads use the different types of objects. When it works well, you don't realize it and can blissfully ignore it; but when you hit a restriction or limitation, it can often be tricky to figure out just what's going on.)


To answer your first question, if I remember my Don Box correctly, every thread MUST call CoInitialize. No exceptions.

As to the automagical part, I have no idea.