LibUsbDotNet:退出WPF应用程序时出错 - 安全句柄已关闭

mmv*_*sbg 4 c# wpf usb libusb libusbdotnet

在WPF应用程序中使用USB设备,我可以成功连接并向设备发送命令.设备只接收命令,没有回复,所以我需要的是一个与之通信的EndpointWriter.

MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
    wholeUsbDevice.SetConfiguration(1);
    wholeUsbDevice.ClaimInterface(0);
}

writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
Run Code Online (Sandbox Code Playgroud)

然后写入设备的过程:

byte[] update = { some bytes };
int bytesWritten;

if (MyUsbDevice != null)
{
     ec = writer.Write(update, 2000, out bytesWritten);
}
Run Code Online (Sandbox Code Playgroud)

一切正常,包括关闭应用程序,除非在工作过程中USB设备断开然后重新连接.应用程序成功处理此方案并重新连接到设备,继续成功向其发送命令:

public bool reconnect()
{
    //clear the info so far
    if (MyUsbDevice != null)
    {
        writer.Dispose();
        wholeUsbDevice.ReleaseInterface(0);
        wholeUsbDevice.Close();
        MyUsbDevice.Close();
        UsbDevice.Exit();
    }

    //now start over
    MyUsbFinder = new UsbDeviceFinder(vid, pid);
    MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
Run Code Online (Sandbox Code Playgroud)

......等等.

在发生此类断开/重新连接后关闭应用程序时会发生此问题.虽然该程序成功运行并与设备通信了很长一段时间,但在退出时我得到以下异常:

System.ObjectDisposedException was unhandled
  Message="Safe handle has been closed"
  Source="mscorlib"
  ObjectName=""
  StackTrace:
       at System.StubHelpers.StubHelpers.SafeHandleC2NHelper(Object pThis, IntPtr pCleanupWorkList)
       at LibUsbDotNet.Internal.Kernel32.GetOverlappedResult(SafeHandle hDevice, IntPtr lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
       at LibUsbDotNet.Internal.LibUsb.LibUsbAPI.GetOverlappedResult(SafeHandle interfaceHandle, IntPtr pOverlapped, Int32& numberOfBytesTransferred, Boolean wait)
       at LibUsbDotNet.Internal.OverlappedTransferContext.Wait(Int32& transferredCount, Boolean cancel)
       at LibUsbDotNet.Main.UsbTransfer.Wait(Int32& transferredCount)
       at LibUsbDotNet.Main.UsbTransfer.Dispose()
       at LibUsbDotNet.Main.UsbTransfer.Finalize()
  InnerException: 
Run Code Online (Sandbox Code Playgroud)

我在usb设备上尝试了许多不同的Dispose和Exit变体,即终点编写器,但到目前为止还没有成功.我假设在断开连接之前仍有一些东西打开,所以我得到了这个错误,但我不确定它是什么以及如何摆脱它.

因为这只发生在关闭应用程序时,我不介意甚至能够以某种方式忽略异常并让应用程序死掉但是我不确定如何捕获该异常,因为Window_Closing事件成功返回然后异常之后发生,所以我无法抓住它......

任何提示赞赏,谢谢!

Ale*_*aus 5

我在Windows服务中收到了类似的异常.我的调用堆栈如下:

Exception Info: System.ObjectDisposedException
Stack:
   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean ByRef)
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(System.Runtime.InteropServices.SafeHandle, Boolean ByRef)
   at LibUsbDotNet.Internal.Kernel32.GetOverlappedResult(System.Runtime.InteropServices.SafeHandle, IntPtr, Int32 ByRef, Boolean)
   at LibUsbDotNet.Internal.LibUsb.LibUsbAPI.GetOverlappedResult(System.Runtime.InteropServices.SafeHandle, IntPtr, Int32 ByRef, Boolean)
   at LibUsbDotNet.Internal.OverlappedTransferContext.Wait(Int32 ByRef, Boolean)
   at LibUsbDotNet.Main.UsbTransfer.Dispose()
   at LibUsbDotNet.Main.UsbTransfer.Finalize()
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我LibUsbDotNet.Internal.LibUsb.LibUsbAPI.GetOverlappedResult()通过添加一个检查来修复方法interfaceHandle.IsClosed.现在该方法如下:

public override bool GetOverlappedResult(SafeHandle interfaceHandle, IntPtr pOverlapped, out int numberOfBytesTransferred, bool wait)
{
    // To prevent ObjectDisposedException check if SafeHandle's been closed
    if (!interfaceHandle.IsClosed)
        return Kernel32.GetOverlappedResult(interfaceHandle, pOverlapped, out numberOfBytesTransferred, wait);
    else
    {
        numberOfBytesTransferred = 0;
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.