Suggested solution for closing worker thread not exiting bug

Jul 14, 2011 at 4:30 AM
Edited Jul 14, 2011 at 4:42 AM

I stumbled upon a bug that I think two other people (one in Discussions, one in Reviews) may have also found.

There is a worker thread called CommEventThread() in Port.cs.
The thread has two mains parts
  1)  Wait for an interesting event to happen such as the RX_CHAR event indicating some data has arrived. This uses WaitCommEvent() for this
  2) Then Read some data using ReadFile()


On the Full Franework (ie on the PC and not on WinCE devices) WaitCommEvent() is not passed an Overlap Structure.
So it blocks forever waiting for an event to come in. There is no timeout on WaitCommEvent().
The only way it will return to the worker thread is for an event to happen (eg some data received).

My test setup uses some USB to Serial Port Dongles. The main one I use has the Prolific 2302 chipset. I also have one with an FDTI chipset.

Windows XP box with the Prolific USB to Serial Device
Open() the serial port.
Close() the serial port.
The worker thread exists. I believe the WaitCommEvent spots that the handle (hPort) has gone invalid and WaitCommEvent() returns.

Vista box with the Prolific USB to Serial Device - Shows the problem

Open() the serial port.
Close() the serial port.
The worker thread never exits. You can see the process sticking around in Task Manager.
WaitCommEvent does not spot that the handle (hPort) has gone invalid and WaitCommEvent() never returns.
I also tried changing the Event Mask with SetCommMask() which the MSDN developer info should also wake up WaitCommEvent().
That does not work either.

 

Note. Vista box using a USB to Serial adapter with the FDTI Chip works correctly. The worker thread exits

 

I have read the MSDN MTTTY sample code. http://msdn.microsoft.com/en-us/library/ms810467
I have also noticed that the Serial Port is opened in Overlapped mode on the Full Framework.

So really we need to make a small change to WaitCommEvent().

a) It needs to have a proper Overlap structure passed to it
b) This overlap structure will then contain an "Event"
c) We can then use WaitForEvent with a Timeout so that we can block on serial port events, but also time out after say 500ms which will allow us to see if the worker thread needs to terminate.

 

In the mean time, I got my application working by hacking the worker thread. I dropped all the WaitCommEvent() code.
I opened the serial port in non-overlapped mode and then
a) had a worker thread that used a Blocking ReadFile()
b) used the Comm Timeouts so the ReadFile() returns every 50ms so that I can do a special check of the hPort handle to see if it is still valid.

I miss out on all the handshaking, but it got it working on Vista and allowed the worker thread to exit.

 

Will gladly help and test an implementation of this. 

Jan 8, 2013 at 2:51 PM

Roger, 

Do you have any example code for how you edited the OpenNETCF.IO.Serial.Port class to change to non-overlapped mode? I have a simple application that basically sends a one byte command from C# to a microcontroller waiting for serial commands. When the microcontroller receives a command it sends the same message back to C# to "echo" back the command. 

What I've found is that if I put a break point directly on the "port.Output = command" and wait a second before continuing, a data received event is successfully triggered and the input buffer contains the expected response from the microcontroller. If I have no breakpoints however, it seems to send the command to the port but a data received event is never triggered and I wait indefinitely for the microcontroller to respond. It seems like the port code is getting "trapped" in the WaitCommEvent() thread. 

Any help getting this class to work better on the full framework would be much appreciated.

 

Thanks,