Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SerialPort.Close() problem - can't shut down the application with the taskmanager!

This is a major issue - I use a serial port in an application here and I poll the status of the attached device by opening and then closing the port again.

If the device fails, SOMETIMES the SerialPort.Close() - method NEVER returns and this is really a show stopper.

The worst thing is that even shutting down the application using the taskmanager fails, it doesn't work (or it is forbidden, by chance).

The attached device is a POS printer (USB) which simulates COM3, it's an Epson TM-T88IV (a very good model, btw).

Does anyone of you have experience with that?

like image 677
Turing Complete Avatar asked Aug 19 '10 16:08

Turing Complete


2 Answers

Repeatedly opening and closing the port is not recommended. Check the Remarks section in the MSDN Library article for SerialPort.Close(). There's a background thread that needs to shut down before a port can be opened again, that takes time. The amount of time is not predictable.

The Close() method can easily deadlock if the DataReceived event handler is currently running. The most typical way to get the deadlock is calling Control.Invoke() in the event handler. Make sure you don't use any code in the event handler that blocks or requires a thread context switch. Using BeginInvoke() is fine.

Not being able to kill the program is caused by a problem in the serial port device driver. Start Taskmgr.exe, Process tab, View + Select Columns and tick "Handles". If after killing the program, you see the Handles column showing 1 then the serial port driver is hanging on to an I/O request that it doesn't complete. The process cannot terminate until all its kernel mode threads are exited.

There's little you can do about that particular problem, other than hoping for a driver update or switching to another vendor. Especially USB serial port emulators are notorious for having lousy device drivers. You get rid of a troublemaker like that by taking it out the parking lot and running it over with your car several times.

Another typical problem with USB emulators is that they are so easy to disconnect while they are in use. That works about as well as jerking a flash drive out of the socket while Windows is writing to it. It would also be a good way to get the device driver hung .NET versions prior to version 4.0 suffer from a heart attack in a background thread when the device suddenly disappears. Short from upgrading, a small sign next to the connector that says "Do not disconnect while in use!" is a practical workaround. They will anyway but get bored with it after a couple of times.

Fwiw, this is otherwise why the "Safely Remove Hardware" tray icon exists. You'll get a solid "Don't do it!" error as long as your program has the port in use. But of course, the operating system is powerless to get users to actually use it. Apple has a patent on a technique to make it fail-safe, detecting the user's fingers on the device :)

like image 150
Hans Passant Avatar answered Nov 10 '22 08:11

Hans Passant


Prior to .Net 4.0 a lot could go wrong with USB to SerialPort devices(crash program/system, etc.). It was easy to test the errors by pulling the USB adapter with the port active.

Recently I ran some tests using .Net 4.0 and it is fixed(certainly improved)??? The test was a simple RX / TX through a USB SerialPort with a loopback, and pull the USB adapter while in use. My program did not crash, and I was able to re-open the port! This is a major improvement.

like image 25
dbasnett Avatar answered Nov 10 '22 06:11

dbasnett