问题
I am working on a c# project where i communicate with an USB device. I open the connection with:
[DllImport("Kernel32.dll", SetLastError = true)]
static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string filename, [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess, [MarshalAs(UnmanagedType.U4)]FileShare fileshare, int securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, int flags, IntPtr template);
private Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle;
...
safeFileHandle = CreateFile("\\\\.\\HsiUsb1", FileAccess.ReadWrite,FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero);
if (safeFileHandle.IsInvalid)
{
return Marshal.GetLastWin32Error();
}
var HsiPort = new FileStream(safeFileHandle, FileAccess.ReadWrite);
if (!HsiPort.CanRead)
{
return -1;
}
The connection is closed with:
if (HsiPort != null)
{
HsiPort.Close();
HsiPort = null;
}
if (safeFileHandle != null)
{
safeFileHandle.Close();
safeFileHandle = null;
}
As long as I read and write data to/from the FileStream synchroneously everything is fine and I can close and open the usb connectione several times. However, since the USB device sends data upon certain events and it is not known how many bytes are sent the programm will be stuck with the FileStream.Read(). So I started to read the data asynchroneously with FileStream.BeginRead () and EndRead(). Everything works fine, however, when I close the connection and start it again the handle is not valid and the obtained error code is 5. Can anyone help me with this? How can I close the SafeFileHandle properly? Thanks in advance
回答1:
Try make use of using statements as the base of SafeFileHandle
implements IDisposable.
The following should work just fine:
[DllImport("Kernel32.dll", SetLastError = true)]
static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string filename, [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess, [MarshalAs(UnmanagedType.U4)]FileShare fileshare, int securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, int flags, IntPtr template);
//private Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle;
public static int doSomething()
{
using (var safeFileHandle = CreateFile("\\\\.\\HsiUsb1", FileAccess.ReadWrite, FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero))
{
if (safeFileHandle.IsInvalid)
{
return Marshal.GetLastWin32Error();
}
using (var HsiPort = new FileStream(safeFileHandle, FileAccess.ReadWrite))
{
if (!HsiPort.CanRead)
{
return -1;
}
}
}
return 0;
}
If you want to use the file handle later within another method. Do remove the first using block. Then you would have to make sure you dispose the handle correctly whenever you are done with the work on that file.
Implementing IDisposable
youself within your class and dispose the resources would be one (good) way to do this.
来源:https://stackoverflow.com/questions/20827222/how-to-close-safefile-handle-properly