[英]CoInitialize Called from BackgroundWorker C#
I have a C# Windows Form application that utilizes a C++ DLL. 我有一个利用C ++ DLL的C#Windows窗体应用程序。 Within the DLL, I initialize COM:
在DLL中,我初始化COM:
auto hResult = CoInitialize(NULL); // Initialize COM
if (hResult != S_OK && hResult != S_FALSE) {
WSACleanup();
return 1;
}
When I run the DLL outside of a BackgroundWorker process, everything works fine. 当我在BackgroundWorker进程之外运行DLL时,一切正常。 If I do though, my application freezes when the DLL is finished.
如果我这样做,则DLL完成后我的应用程序将冻结。 So, I'm attempting to use a BackgroundWorker;
因此,我正在尝试使用BackgroundWorker。 but whenever I run the DLL within the DoWork function I am unable to initialize COM.
但是每当我在DoWork函数中运行DLL时,都无法初始化COM。
Could someone explain this, please, and offer any suggestions on how to run my DLL in the BackgroundWorker? 有人可以解释一下,并提供有关如何在BackgroundWorker中运行我的DLL的任何建议吗?
Thank you. 谢谢。
BackgroundWorker
uses thread pool threads. BackgroundWorker
使用线程池线程。 .NET thread pool threads are automatically initialized to MTA ( CoInitializeEx(NULL, COINIT_MULTITHREADED)
). .NET线程池线程会自动初始化为MTA(
CoInitializeEx(NULL, COINIT_MULTITHREADED)
)。 Your DLL is trying to initialize the thread to STA ( CoInitialize()
), and that call should be returning RPC_E_CHANGED_MODE
. 您的DLL试图将线程初始化为STA(
CoInitialize()
),并且该调用应返回RPC_E_CHANGED_MODE
。 This is a failure. 这是失败的。
Typically, I wouldn't initialize COM on the calling thread from within a library. 通常,我不会从库中在调用线程上初始化COM。 I would consider this an antipattern.
我认为这是一种反模式。 Multiple libraries can be used by a single client application, and each of those libraries might (try to) initialize COM.
单个客户端应用程序可以使用多个库,并且每个库都可以(尝试)初始化COM。 A better design is to have the owner of each thread initialize COM on that thread.
更好的设计是让每个线程的所有者在该线程上初始化COM。 Your client application would initialize COM for the main thread and any background threads it owns (.NET does all this for you).
您的客户端应用程序将为主线程及其拥有的任何后台线程初始化COM(.NET为您完成所有这些操作)。 Each library would specify (in documentation) the threading/apartment requirements for its entry points (eg "This DLL's
FooExport
function must be called from an STA thread."). 每个库都会(在文档中)为其入口点指定线程/
FooExport
要求(例如,“必须从STA线程调用此DLL的FooExport
函数。”)。 Threads owned by the library would have their apartment state controlled by the library. 图书馆拥有的线程的公寓状态将由图书馆控制。 The only real advantage to calling
CoInitialize/Ex
from within the library is to try to detect the apartment state that your thread is currently in so that the library's apartment requirements are checked programmatically, but there are some scenarios (neutral-threaded apartments) in which that becomes problematic. 从库中调用
CoInitialize/Ex
的唯一真正好处是,尝试检测线程当前所在的单元状态,以便以编程方式检查库的单元需求,但是在某些情况下(中性线程单元)这成为问题。
To your scenario: 对于您的方案:
SetApartmentState
). SetApartmentState
)。 Also consider removing the CoInitialize
call in your library. CoInitialize
调用。 CoInitialize
call from your DLL, or use CoInitializeEx(NULL, COINIT_MULTITHREADED)
. CoInitialize
调用,或者使用CoInitializeEx(NULL, COINIT_MULTITHREADED)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.