首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LibUsbDotNet:关闭了退出WPF应用程序安全句柄的错误

LibUsbDotNet:关闭了退出WPF应用程序安全句柄的错误
EN

Stack Overflow用户
提问于 2013-12-30 14:03:46
回答 2查看 1.9K关注 0票数 4

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

代码语言:javascript
复制
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);

然后是写入设备的过程:

代码语言:javascript
复制
byte[] update = { some bytes };
int bytesWritten;

if (MyUsbDevice != null)
{
     ec = writer.Write(update, 2000, out bytesWritten);
}

所有工作都很好,包括关闭应用程序,除非在工作过程中USB设备断开,然后重新连接。应用程序成功地处理此场景并重新连接到设备,并继续成功地向其发送命令:

代码语言:javascript
复制
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);

..。以此类推。

在发生这种断开/重新连接之后,当我关闭应用程序时会发生问题。虽然该程序成功地工作并与设备进行了相当长时间的通信,但在退出时我得到了以下例外情况:

代码语言:javascript
复制
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: 

我在usb设备上尝试了许多不同的配置和退出方式,也就是端点程序,但到目前为止还没有成功。我假设一些东西在断开之前仍然是开放的,所以我得到了这个错误,但是我不知道它是什么,以及如何摆脱它。

因为只有在关闭应用程序时才会发生这种情况,我甚至不介意以某种方式忽略异常并让应用程序分片死亡,但我不知道如何捕获该异常,因为Window_Closing事件成功返回,然后异常发生,因此我无法捕获它……

任何小费都要感谢,谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-19 09:57:53

在关闭我的WPF应用程序时,我也遇到了类似的问题:“安全句柄已关闭”ObjectDisposedException正在发生。

我的堆栈有点不同:

代码语言:javascript
复制
System.ObjectDisposedException was unhandled  
  HResult=-2146232798  
  Message=Safe handle has been closed  
  Source=mscorlib  
  ObjectName=""  
  StackTrace:  
       at System.Threading.WaitHandle.WaitOneNative(SafeHandle waitableSafeHandle, UInt32 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)  
       at System.Threading.WaitHandle.InternalWaitOne(SafeHandle waitableSafeHandle, Int64 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)  
       at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)  
       at LibUsbDotNet.Main.UsbTransfer.get_IsCancelled()  
       at LibUsbDotNet.Main.UsbTransfer.Dispose()  
       at LibUsbDotNet.Main.UsbTransfer.Finalize()  
  InnerException:

但是,通过在我的发送和接收函数中添加以下代码,我成功地修复了它。

代码语言:javascript
复制
using (UsbEndpointWriter writer = device.OpenEndpointWriter(WriteEndpoint))
{
    UsbTransfer usbTransfer = null;

    try
    {
        // Code to do transfer here .. not shown as not pertinent here..
    }
    finally
    {
        if (usbTransfer != null)
        {
            // **** Start of code added to fix ObjectDisposedException
            if (!usbTransfer.IsCancelled || !usbTransfer.IsCompleted)
            {
                usbTransfer.Cancel();
            }
            // **** End of code added to fix ObjectDisposedException
            usbTransfer.Dispose();
        }
    }
}

希望这个片段可以帮助其他人在解决问题的同时发现这个问题。

票数 3
EN

Stack Overflow用户

发布于 2014-10-09 04:20:58

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

代码语言:javascript
复制
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()

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

代码语言:javascript
复制
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;
    }
}

希望能帮上忙。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20841117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档