I am developing for CE, so I do not know how this applies to Windows. I have had the same bug that has been mentioned a few times around the forums. This has to do with the WaitCommEvent() hanging. In our case, the WaitCommEvent() will hang because there is no event or data being sent for it to trigger. If there is a serial device spilling data on the line for for the WaitCommEvent() to pick up, the close will work fine. When the Close() is started, The first action is to close the handle to the port, then invalidate the handle. A problem with this is that WaitCommEvent() does not care. The Thread is supposed to catch an invalid hadle and close down. The Close() needs to set a flag for closure which is checked in the while loop in the thread instead of the Invalid handle. And the one other thing that needs to happen is one final event to break the WaitCommEvent() block, and that is simply a call to m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE).
The code below is our changes for CE, but there will need to be some cleanup. It is more of a hack right now. I just added a single global bool for the shutdown flag, but I know I could have used another existing flag.
public bool Close()
{
if(txOverlapped != IntPtr.Zero)
{
LocalFree(txOverlapped);
txOverlapped = IntPtr.Zero;
}
if(!isOpen) return false;
isOpen = false; // to help catch intentional close
m_bShutdown = true;
if(CommAPI.FullFramework)
{
m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC);
}
else
{
m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE);
}
if(m_CommAPI.CloseHandle(hPort))
{
hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE;
m_CommAPI.SetEvent(closeEvent);
isOpen = false;
hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE;
m_CommAPI.SetEvent(closeEvent);
return true;
}
return false;
}
And this is the changes for the thread
while(!m_bShutdown)
{
// wait for a Comm event
if(!m_CommAPI.WaitCommEvent(hPort, ref eventFlags))
{
Tom Kuhn