I'm struggling with running a function from an ActiveX DLL (compiled from VB6) in a background thread from a C# WinForms application.
Because the VB6 DLL project contains a lot of references to an old library called Sheridan Controls (threed32.ocx), which I'm helpfully informed "doesn't support multi threaded mode", I have to set the Threading Model option to Single Threaded (instead of Apartment Threaded) when compiling the DLL in VB6. So even though I set the ApartmentState property to STA on the C# Thread object from which I invoke the DLL, it still ends up clogging up the UI thread.
I'm not sure what my options are at this point. Refactoring out the Sheridan Controls from the DLL would be a tedious job. Another is just to accept defeat and let the UI hang while the DLL does its work.
I guess my main question is; does anyone know of a way I could (without too much hassle) run the single threaded ActiveX DLL in a separate process/service that could be invoked asynchronously from the main C# thread? Or is there any other option that I'm not aware of?
Solved: Based on the information from user @mnistic, I was able to find a solution. I had to rebuild the ActiveX DLL as an ActiveX EXE, which runs as an out-of-process component. To get it working I had to set "Start Mode" to "Standalone" in project properties. I also set the Instancing parameter on the VB6 class to SingleUse, to ensure that global state would not be shared across instances.
After updating the project reference, I was able to invoke the functions in the library in background threads from my C# application without causing GUI lag.
When it comes to ActiveX, Microsoft differentiates between in-process and out-of-process components. Sometimes when people talk about ActiveX they are referring to in-process components, dll or ocx files that run in the same process as the client that's using them. Typically these components include GUI elements that VB6 made easy to embed within the client application. However, an in-process component must use the client's thread of execution, which in your case was causing the perceived lockup in main thread.
This is what out-of-process components are for. They execute in a separate thread -- separate process as a matter of fact. The drawback is that the communication needs to cross process boundaries, but in your case that's not a concern, and they are relatively easy to set up: https://msdn.microsoft.com/en-us/library/aa262334%28v=vs.60%29.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With