1

我有一个串行端口从嵌入式设备异步接收数据。用户可以选择随时终止与端口的连接,但这意味着如果用户在传输过程中断开连接(有时程序只是暂停myPort.Close()),我会遇到异常。有没有办法可以添加“等到空”命令?下面是这样的吗?

private void tsDisconnect_Click(object sender, EventArgs e)
{
      try
      {
          while(myPort.BytesToRead > 0)
          {//wait here}
      }
      myPort.Close();
}
4

1 回答 1

4

等待并不能解决调用 Close() 导致的死锁,您需要解决核心问题。它几乎总是由 DataReceived 事件处理程序中的代码引起的。我们看不到它,但一个非常常见的错误是使用 Control.Invoke() 或 Dispatcher.Invoke()。

在事件处理程序返回之前,串行端口无法关闭。但它无法返回,因为它卡在 Invoke() 调用中。由于您的 UI 线程很忙,因此无法完成,它卡在 Close() 调用中。或者正在等待 BytesToRead 变为 0,即您所追求的解决方案。也不起作用,您的 DataReceived 事件处理程序被卡住并且不再读取。死锁城。

您需要修复该代码并改用 BeginInvoke()。那是一个非阻塞调用,它不会导致死锁。

死锁还有其他可能的原因。易于诊断,您有很多时间来调试它:) 使用 Debug + Break All,然后使用 Debug + Windows + Threads。双击主线程并查看其调用堆栈以查看 UI 线程在做什么。

于 2013-07-15T17:59:17.473 回答