英文:
FileStream.Dispose throws UnauthorizedAccessException how to handle disposing?
问题
FileStream
是从指向USB Printing Support
驱动程序的SafeHandle
创建的,因此它不是常规的FileStream
。
现在我正在尝试解决一个问题,当用户拔下并重新插入USB设备时。一个新的句柄被创建,而旧的句柄现在指向其他位置。我需要重新初始化连接,但在创建新连接之前,我的直觉是释放旧资源。
> 释放所有可释放的资源
当我尝试释放这个FileStream
时,我得到了UnauthorizedAccessException
,并显示常规消息访问路径被拒绝
。我是否只需在Disconnect
方法中将Dispose调用包装在try/catch
块中,并将它们保持未释放状态?也许在USB I/O方面有比FileStream
更好的方法?
以下是一些代码:
public void Connect()
{
Disconnect();
_printerHandle = UsbPrinterResolver.OpenUSBPrinter(ConnectionString);
_printerStream = new FileStream(_printerHandle, FileAccess.ReadWrite);
}
protected void Disconnect()
{
_printerStream?.Dispose(); // 仅在USB连接正常且有效时起作用
_printerHandle?.Dispose();
_printerStream = null;
_printerHandle = null;
}
UsbPrinterResolver
实际上是来自问题确定打印机名称对应哪个设备ID的解决方案,我只是修改了//FIXME
部分。但是解析的句柄似乎工作得很好。
英文:
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.
答案1
得分: 1
FileStream
在释放之前会在内部刷新流。
因此,你只需要在释放该对象的外部捕获异常。
至于释放句柄:无论如何,它都会被关闭,你不需要释放它,因为流“拥有”该句柄。请参见这里的源代码。所以你不需要保留它。
public void Connect()
{
Disconnect();
var printerHandle = UsbPrinterResolver.OpenUSBPrinter(ConnectionString);
try
{
_printerStream = new FileStream(_printerHandle, FileAccess.ReadWrite);
}
catch
{
printerHandle.Dispose(); // 如果 FileStream 构造函数失败,需要释放句柄
throw;
}
}
protected void Disconnect()
{
_printerStream?.Dispose();
_printerStream = null;
}
英文:
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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论