我只是用這個修正了一個錯誤:的ApartmentState傻瓜
_Thread.SetApartmentState(ApartmentState.STA);
現在我想明白這意味着什麼,以及爲什麼它的作品!
我只是用這個修正了一個錯誤:的ApartmentState傻瓜
_Thread.SetApartmentState(ApartmentState.STA);
現在我想明白這意味着什麼,以及爲什麼它的作品!
COM是.NET的盛大父親。他們有很高的目標,COM做的事情之一,但是.NET完全跳過了這個目標,爲類提供了線程保證。一個COM類可以發佈它具有的線程要求。 COM基礎架構確保滿足這些要求。
這在.NET中完全沒有。例如,您可以在多個線程中使用隊列<>對象,但如果未正確鎖定,則代碼中會有一個非常難以診斷的惡意錯誤。
COM線程的確切詳細信息太大,不適合發佈。我將專注於您的問題的具體內容。創建COM對象的線程必須告訴COM對於具有受限線程選項的COM類給予什麼樣的支持。絕大多數這些類只支持所謂的Apartment線程,它們的接口方法只能從創建實例的相同線程安全地調用。換句話說,他們宣佈「我不支持線程,請注意永不從錯誤的線程呼叫我」。即使客戶端代碼實際上是確實從另一個線程調用它。
有兩種STA(單線程公寓)和MTA。它在CoInitializeEx()調用中指定,函數必須由任何對COM執行任何操作的線程調用。 CLR在啓動線程時自動進行該調用。對於程序的主啓動線程,它將獲得從Main()方法的[STAThread]或[MTAThread]屬性傳遞的值。默認是MTA。對於您自己創建的線程,由您對SetApartmentState()的調用確定。默認是MTA。線程池線程始終是MTA,無法更改。
Windows中有很多需要STA的代碼。值得注意的例子是剪貼板,拖放和外殼對話框(如OpenFileDialog)。 WPF或Windows窗體項目的UI線程應始終爲STA,就像創建窗口的任何線程一樣。
你做出的承諾,COM,你的線程是STA但確實需要你遵循單線程公寓的合同。他們非常僵硬,當你違約時你很難診斷麻煩。要求是你從來沒有阻塞任何時間的線程,你泵送一個消息循環。後者的要求通過WPF或Winforms的UI線程滿足,但如果您創建自己的STA線程,則需要自己處理。破壞合同的常見診斷是僵局。
CLR內置了相當多的支持來支持這些要求,幫助您擺脫困境。例如,鎖語句會在STA線程上阻塞時抽取消息循環。大多數同步類也是如此,Mutex是一個明顯的例外。然而,這隻需要注意從不阻止的要求,您仍然需要創建自己的消息循環。 WPF和Winforms中的Application.Run()。
我以前提供了一個答案,其中包含了有關讓消息循環保持COM快樂的重要性的更多細節。你會發現post here。
[This](http://stackoverflow.com/questions/165316/stathread-and-multithreading)文章可以幫助您 – 2010-11-11 12:45:14