Reputation: 2413
I have a serial port receiving data from an embedded device asynchronously. The user has the option to terminate the connection with the port at any time but this means that I get an exception if the user disconnects mid-transmission (sometimes the program just halts on myPort.Close()
). Is there a way I can add a 'wait until empty' command? Something like this below?
private void tsDisconnect_Click(object sender, EventArgs e)
{
try
{
while(myPort.BytesToRead > 0)
{//wait here}
}
myPort.Close();
}
Upvotes: 1
Views: 1248
Reputation: 942267
Waiting doesn't fix the deadlock you get from calling Close(), you'll need to fix the core problem. It is almost always caused by the code in your DataReceived event handler. We cannot see it, but a very common mistake is to use Control.Invoke() or Dispatcher.Invoke().
A serial port cannot close until the event handler returns. But it can't return because it is stuck in the Invoke() call. Which cannot complete because your UI thread is busy, it is stuck in the Close() call. Or is waiting for BytesToRead to get to 0, the solution you are pursuing. Won't work either, your DataReceived event handler is stuck and not reading anymore. Deadlock city.
You'll need to fix that code and use BeginInvoke() instead. That's a non-blocking call, it can't cause deadlock.
There are other possible reasons for deadlock. Easy to diagnose, you've got lots of time to debug it :) Use Debug + Break All, then Debug + Windows + Threads. Double-click the Main thread and look at its call stack to see what the UI thread is doing.
Upvotes: 4