使用LibUsbDotNet时,当关闭后再打开USB设备就会报“已关闭safe handle”

由于项目中需要和USB设备通讯,于是用到LibUsbDotNet.dll这个开源的项目。但是在使用的时候发现关闭USB设备后再打开,过2秒就会出现异常“已关闭safe handle”,由于网上关于LibUsbDotNet的资料比较少,查了好久都查不出原因。不过用关键字“已关闭safe handle”的时候,发现很多人使用SerialPort时也遇到这个问题。

由于对底层实现不懂,所以只能猜测原因。在使用Usb.read()或者SerialPort.read()方法的时候,都会开辟一个局部变量数组用来保存读取的数据,然后将这个数组引用作为参数传入方法。这些方法是线程阻塞的,但是只是表面上的阻塞,底层可能保存着数组的句柄,并且一直尝试读取数据并转移到数组。这样如果中止线程的话,C#的垃圾回收机制会回收到线程的数组,而这时候设备没有关闭,read()方法仍然在尝试将数据转移到已经被释放的数组中。这时候如果来数据了,就会报“已关闭safe handle”。
而大部分人在使用Usb或者SerialPort通讯时,都会开出一个线程,线程中申请数组然后循环往数组中读取数据。而在关闭设备的时候,都会先去中止读取线程,然后再关闭设备。这样一来就中招了。。。

解决的办法很简单,两个方法:1、使用全局数组变量作为参数传入到方法中。这样在中止线程的时候不会回收。2、先关闭设备,再中止线程。

当然了,这一切都是猜测,不过使用了这两个方法之后,就没有错误了。。。可能是猜中原因了?

一直报错时的代码:

 1 /// <summary>
 2         /// 关闭USB设备
 3         /// </summary>
 4         public static void closeDevice()
 5         {
 6             //停止监听线程
 7             EndListenThread();
 8             //停止读线程
 9             try
10             {
11                 ReadThread.Abort();
12             }
13             catch
14             { }
15             finally
16             {
17                 ReadThread = null;
18             }
19
20             if (!ReferenceEquals(usbDevice, null))
21                 usbDevice.Close();
22             if (!ReferenceEquals(usbReader, null))
23                 usbReader.Dispose();
24             if (!ReferenceEquals(usbWriter, null))
25                 usbWriter.Dispose();
26
27             GlobalStatus.Devicestatus = false;
28             Console.WriteLine("关闭设备!");
29
30             //USB关闭事件通知
31             if (UsbDeviceChanged != null)
32             {
33                 UsbDeviceChanged("UsbNotice", new UsbConnectionEventArgs(0, false));
34             }
35         }

只是将设备关闭的位置换了一下,困扰我很长时间的问题就消失了。。。

 1 /// <summary>
 2         /// 关闭USB设备
 3         /// </summary>
 4         public static void closeDevice()
 5         {
 6             if (!ReferenceEquals(usbDevice, null))
 7                 usbDevice.Close();
 8             if (!ReferenceEquals(usbReader, null))
 9                 usbReader.Dispose();
10             if (!ReferenceEquals(usbWriter, null))
11                 usbWriter.Dispose();
12
13             //停止监听线程
14             EndListenThread();
15             //停止读线程
16             try
17             {
18                 ReadThread.Abort();
19             }
20             catch
21             { }
22             finally
23             {
24                 ReadThread = null;
25             }
26
27             GlobalStatus.Devicestatus = false;
28             Console.WriteLine("关闭设备!");
29
30             //USB关闭事件通知
31             if (UsbDeviceChanged != null)
32             {
33                 UsbDeviceChanged("UsbNotice", new UsbConnectionEventArgs(0, false));
34             }
35         }

使用LibUsbDotNet时,当关闭后再打开USB设备就会报“已关闭safe handle”

时间: 2024-12-21 09:18:42

使用LibUsbDotNet时,当关闭后再打开USB设备就会报“已关闭safe handle”的相关文章

dbgview 在windows 10 中关闭后再次打开时无法“capture kernel”

DbgView 是一个免费的用于抓取log 的工具,可以捕获并输出OutputDebugString()函数的输出,以及输出windows driver 中dbgprint 的log,对于windows driver 开发和调试是十分有帮助的. 但是该tool 已经很久不再更新了,最新的版本是V4.81 版本,是久远的2012年12月份release 出来的,具体下载链接为: https://technet.microsoft.com/en-us/sysinternals/debugview.a

eclipse中关闭java文件后再打开,找不到如何切换可视化编辑器

http://www.iteye.com/problems/64806 两种方式:   第一种正如楼上的老兄说的.在该java类中,鼠标右击,移动到openWith上 找到jigloo,找不到就在othor里面找jigloo.   第二种方式,是将所有的.java文件都用jigloo打开,       window - preferences - general -  editors - file association - 把java 用jigloo 设为默认打开

Eclipse 强制关闭后无法打开的解决办法

最狠的解决方法是删除workspace/.metadata/目录,也就是把这个workspace从eclipse的记忆中删除,缺点是要重新加载每一个项目... 网上很流行的一个方法是: $ rm YOUR_PROJECT_DIR/.metadata/.plugins/org.eclipse.core.resources/.snap

inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效

inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效 inno setup 安装卸载时检测程序是佛正在运行卸载完成后自动打开网页-代码无效 --------------------------代码如下--------------------------- [Code]varErrorCode: Integer;IsRunning: Integer; // 安装时判断客户端是否正在运行function InitializeSetup(): Boolean;beginResult

eclipse在异常关闭后,导致无法启动workspace问题的解决

现象: 现在大多数java开发者使用的IDE都是eclipse,而且一般在一个workspace中,会有很多个项目,有些是open的,有些是关闭的.有时候eclipse在使用过程中会莫名其妙的异常中断关闭,再打开eclipse,选择workspace后,会一直停留在加载的页面上无法进入eclipse平台. 问题分析: 这个问题一直碰到,但具体原因不清楚,可能需要eclipse的开发工程师才能回答. 问题解决: 这个问题的解决办法至少有两个. 1.一个办法就是删除这个workspace的整个met

浏览器关闭后,Session会话结束了么?

今天想和大家分享一个关于Session的话题: 当浏览器关闭时,Session就被销毁了? 我们知道Session是JSP的九大内置对象(也叫隐含对象)中的一个,它的作用是可以保 存当前用户的状态信息,初学它的时候,认为Session的生命周期是从打开一个浏览器窗 口发送请求到关闭浏览器窗口,但其实这种说法是不正确的!下面就具体的去解释: 当用户第一次访问Web应用中支持Session的某个网页时,就会开始一个新的Session, 那么接下来当用户浏览这个Web应用的不同网页时,始终处于一个Se

executequery要求已打开且可用的connection,连接的当前状态为已关闭

问题: executequery要求已打开且可用的connection,连接的当前状态为已关闭 错误原因: 连接的当前状态为已关闭.或者只创建了Connection对象,没有调用Connection.Open()方法: 也就是:connection.State != ConnectionState.Closed 解决方法: 调用Connection.Open()方法: 原文地址:https://www.cnblogs.com/jlutiger/p/9337709.html

红米note怎么打开USB调试模式

红米note到货后,打开USB调试模式是一些新手很棘手的问题,所以要手机助手成功识别红米note,你必须打开红米note的USB调试模式.在安卓4.2版本中,系统的USB调试模式不是非常简单地被打开的.红米note采用的就是基于安卓4.2及以上的MIUI操作系统. 方法/步骤 1.在红米note界面中,您会看到桌面中的"设置"图标,点击进入红米note设置界面. 2.在设置界面中点击"全部设置",然后再界面最底端点击"关于手机"选项. 3.在&q

excel 2007第一次打开时显示there was a problem sending command to the program,再打开一次就能打开了。

excel 2007第一次打开时总是显示there was a problem sending command to the program. 关闭后打开一次就能打开了. 由于装的东西太多,初步怀疑是兼容性的问题. 在Excel option里面的add-in 和 trusted publisher 里面去掉非office的插件. 如下图: 保存后,再次打开, 问题解决. excel 2007第一次打开时显示there was a problem sending command to the p