Due to the need to communicate with USB devices in the project, LibUsbDotNet.dll is used for this open source project. But in use when found to turn off the USB device and then open, after 2 seconds will be abnormal "closed safe handle", because the online information about libusbdotnet Less, check for a long time to find out why. However, when using the keyword "closed safe handle", found that many people use serialport also encountered this problem.
Because the underlying implementation does not understand, so can only guess the reason. When using the Usb.read () or Serialport.read () method, a local variable array is created to hold the read data, and the array reference is passed as a parameter to the method. These methods are thread-blocking, but only surface blocking, the underlying may hold the handle of the array, and always try to read the data and transfer to the array. This way, if the thread is aborted, the C # garbage collection mechanism is recycled to the thread's array, and the device is not closed, and the Read () method is still trying to transfer the data to an array that has already been disposed. At this time, if the data, it will be reported "closed safe handle."
While most people use USB or serialport communication, they will open a thread that requests an array and then loops through the array to read the data. When the device is shut down, it will abort the read thread before shutting down the device. So the middle of the recruit ...
The solution is simple, two methods: 1, the use of global array variables as parameters passed into the method. This will not be recycled when the thread is aborted. 2. Turn off the device first and then abort the thread.
Of course, all this is speculation, but after using these two methods, there is no error ... Could it be the reason for the guess?
Always error code:
1 /// <summary>2 ///turn off the USB device3 /// </summary>4 Public Static voidCloseDevice ()5 {6 //Stop the Listener thread7 Endlistenthread ();8 //stop a read thread9 TryTen { One Readthread.abort (); A } - Catch - { } the finally - { -Readthread =NULL; - } + - if(! ReferenceEquals (Usbdevice,NULL)) + usbdevice.close (); A if(! ReferenceEquals (Usbreader,NULL)) at usbreader.dispose (); - if(! ReferenceEquals (Usbwriter,NULL)) - usbwriter.dispose (); - -Globalstatus.devicestatus =false; -Console.WriteLine ("turn off the device! "); in - //USB Shutdown Event Notification to if(Usbdevicechanged! =NULL) + { -Usbdevicechanged ("Usbnotice",NewUsbconnectioneventargs (0,false)); the } *}
Just changed the location of the device off, the problem that bothered me for a long time disappeared ...
1 /// <summary>2 ///turn off the USB device3 /// </summary>4 Public Static voidCloseDevice ()5 {6 if(! ReferenceEquals (Usbdevice,NULL))7 usbdevice.close ();8 if(! ReferenceEquals (Usbreader,NULL))9 usbreader.dispose ();Ten if(! ReferenceEquals (Usbwriter,NULL)) One usbwriter.dispose (); A - //Stop the Listener thread - Endlistenthread (); the //stop a read thread - Try - { - Readthread.abort (); + } - Catch + { } A finally at { -Readthread =NULL; - } - -Globalstatus.devicestatus =false; -Console.WriteLine ("turn off the device! "); in - //USB Shutdown Event Notification to if(Usbdevicechanged! =NULL) + { -Usbdevicechanged ("Usbnotice",NewUsbconnectioneventargs (0,false)); the } *}