在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);然后是写入设备的过程:
byte[] update = { some bytes };
int bytesWritten;
if (MyUsbDevice != null)
{
ec = writer.Write(update, 2000, out bytesWritten);
}所有工作都很好,包括关闭应用程序,除非在工作过程中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);..。以此类推。
在发生这种断开/重新连接之后,当我关闭应用程序时会发生问题。虽然该程序成功地工作并与设备进行了相当长时间的通信,但在退出时我得到了以下例外情况:
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事件成功返回,然后异常发生,因此我无法捕获它……
任何小费都要感谢,谢谢!
发布于 2014-09-19 09:57:53
在关闭我的WPF应用程序时,我也遇到了类似的问题:“安全句柄已关闭”ObjectDisposedException正在发生。
我的堆栈有点不同:
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:但是,通过在我的发送和接收函数中添加以下代码,我成功地修复了它。
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();
}
}
}希望这个片段可以帮助其他人在解决问题的同时发现这个问题。
发布于 2014-10-09 04:20:58
我在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()为了解决这个问题,我通过添加对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;
}
}希望能帮上忙。
https://stackoverflow.com/questions/20841117
复制相似问题