Reputation: 3089
I'm using com interop to talk to some physical piece of hardware.
When I need the current reading from the hardware I have a nice elaborate piece of threading code that keeps it off my UI thread so that I don't lock up the UI while I query the hardware since sometimes it can take as much as 1-2 minutes (although usually more like 1-5 seconds).
So once I step into the com object it bounces back to the main UI thread and the UI becomes busy during the duration of the reading.
The main app is a .net WPF app, so it STA by default. The COM object is created on the main thread, but it's created my a singleton factory, so all of these objects are created by the same few lines of UI.
I'd love to show some code, but it's not like the stuff is in just a few lines of code.
What kind of work arounds are there for this behavior? I'd also love to be able to read from multiple com object simultaneously.
If were to create background threads to spin up these com objects inside my object facotry. How do I keep them alive to handle the work that gets marshaled back to them?
Upvotes: 0
Views: 407
Reputation: 3089
I have it working.
Previously my constructor worked like:
internal class Device
{
private ComDeviceLibrary.UberDevice myDevice;
internal Device(DeviceInitObject myInitOptions)
{
myDevice = new ComDeviceLibrary.UberDevice();
}
}
Now if I do this:
internal class Device
{
private ComDeviceLibrary.UberDevice myDevice;
internal Device(DeviceInitObject myInitOptions)
{
AutoResetEvent createHandle = new AutoResetEvent(false);
Thread creationThread = new Thread(CreateDevice);
creationThread.IsBackground = false;
creationThread.SetApartmentState(ApartmentState.MTA);
creationThread.Start(createHandle);
createHandle.WaitOne();
}
private void CreateDevice(object objWaitHandle)
{
myDevice = new ComDeviceLibrary.UberDevice();
((AutoResetEvent)objWaitHandle).Set();
}
}
It works!
Upvotes: 1
Reputation: 1545
"I have a nice elaborate piece of threading code" - This has a 'famous last words' ring to it.
"The COM object is created on the main thread, but it's created my a singleton factory, so all of these objects are created by the same few lines of UI."
If your COM object was created in your GUI thread, why are you surprised when it blocks the GUI thread? Why not create the COM object in the thread that directly talks to the hardware?
Upvotes: 0
Reputation: 61398
Assuming the object is apartment threaded - make sure you call it on the same thread that created it. Otherwise the calls will be routed to the object's home thread via Windows messages, thus blocking the UI.
If everything else fails - spawn a worker process.
EDIT: and another point - the worker thread needs to be an STA, and needs a message loop. Otherwise the object lives in the main thread, with routing and UI blocking.
Upvotes: 1