[英]CoInitialize Called from BackgroundWorker C#
我有一個利用C ++ DLL的C#Windows窗體應用程序。 在DLL中,我初始化COM:
auto hResult = CoInitialize(NULL); // Initialize COM
if (hResult != S_OK && hResult != S_FALSE) {
WSACleanup();
return 1;
}
當我在BackgroundWorker進程之外運行DLL時,一切正常。 如果我這樣做,則DLL完成后我的應用程序將凍結。 因此,我正在嘗試使用BackgroundWorker。 但是每當我在DoWork函數中運行DLL時,都無法初始化COM。
有人可以解釋一下,並提供有關如何在BackgroundWorker中運行我的DLL的任何建議嗎?
謝謝。
BackgroundWorker
使用線程池線程。 .NET線程池線程會自動初始化為MTA( CoInitializeEx(NULL, COINIT_MULTITHREADED)
)。 您的DLL試圖將線程初始化為STA( CoInitialize()
),並且該調用應返回RPC_E_CHANGED_MODE
。 這是失敗的。
通常,我不會從庫中在調用線程上初始化COM。 我認為這是一種反模式。 單個客戶端應用程序可以使用多個庫,並且每個庫都可以(嘗試)初始化COM。 更好的設計是讓每個線程的所有者在該線程上初始化COM。 您的客戶端應用程序將為主線程及其擁有的任何后台線程初始化COM(.NET為您完成所有這些操作)。 每個庫都會(在文檔中)為其入口點指定線程/ FooExport
要求(例如,“必須從STA線程調用此DLL的FooExport
函數。”)。 圖書館擁有的線程的公寓狀態將由圖書館控制。 從庫中調用CoInitialize/Ex
的唯一真正好處是,嘗試檢測線程當前所在的單元狀態,以便以編程方式檢查庫的單元需求,但是在某些情況下(中性線程單元)這成為問題。
對於您的方案:
SetApartmentState
)。 還可以考慮刪除庫中的CoInitialize
調用。 CoInitialize
調用,或者使用CoInitializeEx(NULL, COINIT_MULTITHREADED)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.