我有一个串行端口异步接收来自嵌入式设备的数据。用户可以随时选择终止与端口的连接,但这意味着如果用户断开中间传输(有时程序暂停在myPort.Close()
上),我会收到异常。有没有办法可以添加'wait until empty'命令?下面这样的东西?
private void tsDisconnect_Click(object sender, EventArgs e)
{
try
{
while(myPort.BytesToRead > 0)
{//wait here}
}
myPort.Close();
}
答案 0 :(得分:4)
等待并不能解决你从调用Close()中获得的死锁,你需要修复核心问题。它几乎总是由DataReceived事件处理程序中的代码引起的。我们看不到它,但是一个非常常见的错误是使用Control.Invoke()或Dispatcher.Invoke()。
在事件处理程序返回之前,串口无法关闭。但它无法返回,因为它停留在Invoke()调用中。由于你的UI线程很忙,它无法完成,它停留在Close()调用中。或者正在等待BytesToRead达到0,这是您正在追求的解决方案。无法工作,您的DataReceived事件处理程序被卡住而不再阅读。死锁城市。
您需要修复该代码并使用BeginInvoke()代替。这是一个非阻塞的呼叫,它不会导致死锁。
还有其他可能的死锁原因。易于诊断,你有很多时间来调试它:)使用Debug + Break All,然后是Debug + Windows + Threads。双击主线程并查看其调用堆栈以查看UI线程正在执行的操作。