多线程和侦听串行端口
本文关键字:串行端口 多线程 | 更新日期: 2023-09-27 18:25:08
假设我想从串行端口接收一些数据。使用串行的块调用。ReadLine()并使用以下事件。
private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
string line = port.ReadLine();
// PROCESS DATA Somewhere else
}
我从不同的来源阅读,他们都说这是连载。ReadLine有自己的线程,除非使用BeginInvoke,否则我不应该从这个线程修改UI。然而,我注意到,在一段时间内,UI无论如何都会变得没有响应。
这是我的问题。在port_DataReceived中调用新线程是个坏主意吗?我想在另一个线程中接收数据并处理接收到的数据,而不是mythread。Start()放在哪里?我不能一直启动它,我只是想让它知道在收到数据后什么时候独立运行。根据MSDN的说法,一个中止的线程无法再次启动。睡眠冻结了我的用户界面。
您误解了正在发生的事情。SerialPort.ReadLine()不使用线程。它是在另一个线程上运行的DataReceived事件处理程序。这是必要的,这样SerialPort就可以尽快将收到的数据通知您的代码,而无需等待UI线程空闲。这确实意味着你不能直接从事件处理程序更新你的UI,当你尝试时,你会得到一个InvalidOperationException。
DataReceived事件当然可以帮助您避免冻结UI。你的问题中没有太多提示,无法知道你真正的问题可能是什么。一个问题可能是过于频繁地使用Control.BeginInvoke(),用调用请求淹没UI线程,使其无法执行常规任务。比如对输入和绘画做出反应。解决方法是减少调用频率,你只需要让人眼满意,它们不会那么快工作。缓冲接收到的数据,保持UI的输出量合理,这样人类实际上可以看到的不仅仅是模糊。
另一个常见问题是死锁,它将永久冻结您的程序。使用调试器很容易诊断,您会看到您的程序卡在SerialPort.Close()调用上。当您使用Control.Invoke()而不是Control.BeginInvoke()时会发生这种情况。不要使用Invoke(。