I am communicating with an embedded device that periodically shuts down its USB serial port emulation, uses the USB port for something else, and then restarts its serial port emulation. During this brief period the serial port disappears from the windows device manager and also from the registry, and then reappears in both locations.
My .net 4.5 application handles this just fine so long as I am disconnected from the serial port when it occurs: after the serial port emulation has been restarted I can reconnect and communicate as usual.
However, if I am connected to the virtual serial port when the device drops and later restarts its serial port emulation, my program does not hang but I cannot gain access to the restarted port.
In this situation the windows device manager correctly shows the port vanishing and reappearing, while the registry shows the port vanishing but never reappearing. Naturally this means that SerialPort.GetPortNames() subsequently does not find the port, and of course I get an IOException if I attempt to close the port which has vanished.
Edit: I'm not using worker threads, and I am using BaseStream.ReadAsync and I am able to trap the IOException and dispose the original port object.
As I mentioned, the restarted emulated port shows up in Device Manager just fine but does not show up in the registry at HKLM/Hardware/DeviceMap/SerialComm.
Once I have disposed (or even tried and failed to close) the port in .net, if I subsequently force the embedded device to reboot then the emulated port reappears in the registry and I can reconnect to it. Unfortunately this requires physical interaction with the device, which typically is not possible.
I am seeking some way to recover programmatically, because I don't normally have access to the device to force a reboot.
I'm imagining that after I dispose my serial port object there might be some way to get Windows to refresh the registry, but I have been unable to find any clues as to how that might be accomplished.
I've found many SO questions that are similar to mine, but none that are quite the same and none that have provided an answer to my problem.
Hans Passant has suggested placing a tag on the USB cable inviting people to unplug it and plug it back in a few times just to see what happens. I like that thinking, but in my case the emulation is stopped and started by an embedded device -- and that behavior is required due to the design of the hardware.
I tried blindly adding <legacyUnhandledExceptionPolicy enabled="1"/>
to my app.exe.config file, and it didn't seem to do anything.
Based on answers to similar questions I tried moving my call to Close() to a separate thread and also tried using async to await the call to close. That approach terminated my application with a system reflection error.
How can I make my application dispose its connection (or otherwise get out of the way) when a port vanishes and reappears, so the registry can be refreshed properly to match the device manager?
Or is there anything at all I can do to recover from momentary loss of an emulated serial port without terminating and restarting the application?