{"id":4613,"date":"2013-04-19T07:00:00","date_gmt":"2013-04-19T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/04\/19\/why-does-cocreateinstance-work-even-though-my-thread-never-called-coinitialize-the-curse-of-the-implicit-mta\/"},"modified":"2013-04-19T07:00:00","modified_gmt":"2013-04-19T07:00:00","slug":"why-does-cocreateinstance-work-even-though-my-thread-never-called-coinitialize-the-curse-of-the-implicit-mta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130419-00\/?p=4613","title":{"rendered":"Why does CoCreateInstance work even though my thread never called CoInitialize? The curse of the implicit MTA"},"content":{"rendered":"<p>While developing tests, a developer observed erratic behavior with respect to <code>Co&shy;Create&shy;Instance<\/code>:<\/p>\n<blockquote class=\"q\"><p>  In my test, I call <code>Co&shy;Create&shy;Instance<\/code> and it fails with <code>CO_E_NOT&shy;INITIALIZED<\/code>. Fair enough, because my test forgot to call <code>Co&shy;Initialize<\/code>. <\/p>\n<p> But then I went and checked the production code: In response to a client request, the production code creates a brand new thread to service the request. The brand new thread does not call <code>Co&shy;Initialize<\/code>, yet its call to <code>Co&shy;Create&shy;Instance<\/code> <i>succeeds<\/i>. How is that possible? I would expect the production code to also get a <code>CO_E_NOT&shy;INITIALIZED<\/code> error. <\/p>\n<\/blockquote>\n<p> I was able to debug this psychically, but only because I knew about the <i>implicit MTA<\/i>. <\/p>\n<p> The <i>implicit MTA<\/i> is not something I can find very much documentation on, except in the documentation for the <a href=\"http:\/\/msdn.microsoft.com\/library\/dd542638\"> <code>APP&shy;TYPE&shy;QUALIFIER<\/code> enumeration<\/a>, where it mentions: <\/p>\n<blockquote class=\"q\"><p> [The <b>APT&shy;TYPE&shy;QUALIFIER_IMPLICIT_MTA<\/b>] qualifier is only valid when the <i>pAptType<\/i> parameter of the <b>Co&shy;Get&shy;Apartment&shy;Type<\/b> function specifies APT&shy;TYPE_MTA on return. A thread has an implicit MTA apartment type if it does not initialize the COM apartment itself, and if another thread has already initialized the MTA in the process. This qualifier informs the API caller that the MTA of the thread is implicitly inherited from other threads and is not initialized directly. <\/p><\/blockquote>\n<p> Did you get that? If any thread in the process calls <code>Co&shy;Initialize&shy;[Ex]<\/code> with the <code>COINIT_MULTI&shy;THREADED<\/code> flag, then that not only initializes the current thread as a member of the multi-threaded apartment, but it also says, &#8220;Any thread which has never called <code>Co&shy;Initialize&shy;[Ex]<\/code> is also part of the multi-threaded apartment.&#8221; <\/p>\n<p> Further investigation revealed that yes, some other thread in the process called <code>Co&shy;Initialize&shy;Ex(0, COINIT_MULTI&shy;THREADED)<\/code>, which means that the thread which forgot to call <code>Co&shy;Initialize<\/code> was implicitly (and probably unwittingly) placed in the MTA. <\/p>\n<p> The danger of this implicit MTA, of course, is that since you didn&#8217;t know you were getting it, you also don&#8217;t know if you&#8217;re going to lose it. If that other thread which called <code>Co&shy;Initialize&shy;Ex(0, COINIT_MULTI&shy;THREADED)<\/code> finally gets around to calling <code>Co&shy;Un&shy;initialize<\/code>, then it will tear down the MTA, and your thread will have the MTA rug ripped out from under it. <\/p>\n<p> Moral of the story: If you want the MTA, make sure you ask for it explicitly. And if you forget, you may end up in the implicit MTA, whether you wanted it or not. (Therefore, conversely, if you <i>don&#8217;t<\/i> want the MTA, make sure to deny it explicitly!) <\/p>\n<p> <b>Exercise<\/b>: Use your psychic debugging skills to diagnose the following problem. &#8220;When my code calls <code>Get&shy;Open&shy;File&shy;Name<\/code>, it behaves erratically. I saw a Knowledge Base article that says that this can happen <a href=\"http:\/\/support.microsoft.com\/kb\/287087\"> if I initialize my thread in the multi-threaded apartment<\/a>, but my thread does not do that.&#8221; <\/p>\n","protected":false},"excerpt":{"rendered":"<p>While developing tests, a developer observed erratic behavior with respect to Co&shy;Create&shy;Instance: In my test, I call Co&shy;Create&shy;Instance and it fails with CO_E_NOT&shy;INITIALIZED. Fair enough, because my test forgot to call Co&shy;Initialize. But then I went and checked the production code: In response to a client request, the production code creates a brand new thread [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-4613","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>While developing tests, a developer observed erratic behavior with respect to Co&shy;Create&shy;Instance: In my test, I call Co&shy;Create&shy;Instance and it fails with CO_E_NOT&shy;INITIALIZED. Fair enough, because my test forgot to call Co&shy;Initialize. But then I went and checked the production code: In response to a client request, the production code creates a brand new thread [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/4613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=4613"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/4613\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=4613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=4613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=4613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}