The FileStream
is created from SafeHandle
that points directly to USB Printing Support
driver, so it is not a regular FileStream
.
Now I am trying to fix a problem when a user unplugs and re-plugs the USB device. A new handle is created and the old one now points somewhere else. I need to reinitialize the connection, but before creating a new one my instinct is to Dispose the old resources
Dispose everything that is disposable
Trying to dispose this FileStream
I get UnauthorizedAccessException
with regular message Access to the path is denied
. Do I just wrap my Dispose calls in method Disconnect to try/catch
and leave them undisposed as is? Maybe there is a better way for USB I/O than FileStream
?
Here is some code:
public void Connect()
{
Disconnect();
_printerHandle = UsbPrinterResolver.OpenUSBPrinter(ConnectionString);
_printerStream = new FileStream(_printerHandle, FileAccess.ReadWrite);
}
protected void Disconnect()
{
_printerStream?.Dispose(); // only works when the usb connection is working and valid
_printerHandle?.Dispose();
_printerStream = null;
_printerHandle = null;
}
The UsbPrinterResolver
is actually the one from question Figuring which printer name corresponds to which device ID I just modified the //FIXME
part. But the resolved handles seemed to work great.
FileStream
internally flushes the stream before disposing.
So you just need to catch the exception on the outside of whatever is disposing this object.
As far as disposing the handle: it will be closed regardless, you don't need to dispose that because the stream "owns" the handle. See the source code here. So you don't need to keep it around.
public void Connect()
{
Disconnect();
var printerHandle = UsbPrinterResolver.OpenUSBPrinter(ConnectionString);
try
{
_printerStream = new FileStream(_printerHandle, FileAccess.ReadWrite);
}
catch
{
printerHandle.Dispose(); // need to dispose the handle if FileStream ctor fails
throw;
}
}
protected void Disconnect()
{
_printerStream?.Dispose();
_printerStream = null;
}