How to Close SafeFile Handle properly

二次信任 提交于 2021-02-20 18:12:24

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!