Using COM in DLL called by .Net application
-
I have a .Net/WPF application which calls methods on a DLL. One of these methods - Load() - calls CoCreateInstance to load a COM server provided by a third party. If I do all this in the Load() thread, it works fine i.e. Load() calls CoCreateInstance directly. However if Load() creates a worker thread, and then waits for completion, the CoCreateInstance call hangs. If I remove the wait, so that Load() returns before the worker thread completes, it works. The CoCreateInstance call returns AFTER the Load() function returns. :~ Anyone know what is happening? It is as if it is serialising the COM access for some reason ...
-
I have a .Net/WPF application which calls methods on a DLL. One of these methods - Load() - calls CoCreateInstance to load a COM server provided by a third party. If I do all this in the Load() thread, it works fine i.e. Load() calls CoCreateInstance directly. However if Load() creates a worker thread, and then waits for completion, the CoCreateInstance call hangs. If I remove the wait, so that Load() returns before the worker thread completes, it works. The CoCreateInstance call returns AFTER the Load() function returns. :~ Anyone know what is happening? It is as if it is serialising the COM access for some reason ...
Could be an STA / MTA issue. Your UI thread will be STA, but a background thread will usually default to MTA. If your COM component requires STA, then your worker thread will need to be STA. Understanding and Using COM Threading Models[^] Apartments and Pumping in the CLR – cbrumme's WebLog[^] Thread.SetApartmentState Method (ApartmentState) (System.Threading)[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
I have a .Net/WPF application which calls methods on a DLL. One of these methods - Load() - calls CoCreateInstance to load a COM server provided by a third party. If I do all this in the Load() thread, it works fine i.e. Load() calls CoCreateInstance directly. However if Load() creates a worker thread, and then waits for completion, the CoCreateInstance call hangs. If I remove the wait, so that Load() returns before the worker thread completes, it works. The CoCreateInstance call returns AFTER the Load() function returns. :~ Anyone know what is happening? It is as if it is serialising the COM access for some reason ...
You could try calling CoInitialize[^] in the worker thread before the call to
CoCreateInstance
.«_Superman_» _I love work. It gives me something to do between weekends.
_Microsoft MVP (Visual C++) (October 2009 - September 2013)
-
You could try calling CoInitialize[^] in the worker thread before the call to
CoCreateInstance
.«_Superman_» _I love work. It gives me something to do between weekends.
_Microsoft MVP (Visual C++) (October 2009 - September 2013)
Thanks for the comment. Yes I call CoInitialise, that is not the issue. I wish it was. :)
-
Could be an STA / MTA issue. Your UI thread will be STA, but a background thread will usually default to MTA. If your COM component requires STA, then your worker thread will need to be STA. Understanding and Using COM Threading Models[^] Apartments and Pumping in the CLR – cbrumme's WebLog[^] Thread.SetApartmentState Method (ApartmentState) (System.Threading)[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Deleted!
-
Could be an STA / MTA issue. Your UI thread will be STA, but a background thread will usually default to MTA. If your COM component requires STA, then your worker thread will need to be STA. Understanding and Using COM Threading Models[^] Apartments and Pumping in the CLR – cbrumme's WebLog[^] Thread.SetApartmentState Method (ApartmentState) (System.Threading)[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Thanks for the comments. I have tested using a simple Win32 C++ console application to drive our DLL, and it works fine when using the worker thread to invoke COM commands to the third party component. So clearly this is something to do with the .Net application. Okay, I have solved it. A COM STA uses Windows messages to serialise access to the COM object which might not be thread safe. So when I created a worker thread, the main thread then hung waiting for the worker thread to finish, but it never did, as the main thread hanging blocked the message pump! Instead of the main thread waiting, I now make it periodically run a message pump to ensure that messages are process. That has solved the problem. Yikes. I hate COM! Thank you for your helpful post. Added later: I have also looked into removing the worker thread and marshalling the COM interfaces across threads and this works. It has the advantage that I do not have to mess around with a message pump, which is akin to spinning the tyres.