1

Lets say I want to receive some data from the serial port. Using a block call for serial.ReadLine() and using the following event.

private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
        var port = (SerialPort)sender;

        string line = port.ReadLine();

            // PROCESS DATA Somewhere else

}

I was reading from different sources and all of they say that the serial.ReadLine has its own thread and I should not modify the UI from this thread unless using BeginInvoke. However, I notice that during some time the UI will become unresponsive anyway.

So here is my question. Calling a new thread inside port_DataReceived will be a bad idea? I want to receive the data and process the received data in another thread however mythread.Start() where to put it? I cannot be starting it all the time I just want it to know somehow when to run independently after receiving the data. And according to MSDN a aborted thread cannot be started again. Putting Thread.Sleep is freezing my UI.

4

1 回答 1

2

你误解了正在发生的事情。SerialPort.ReadLine() 不使用线程。它是在另一个线程上运行的 DataReceived 事件处理程序。有必要这样 SerialPort 可以尽快通知您的代码有关接收到的数据,而无需等待您的 UI 线程空闲。这确实意味着您不能直接从事件处理程序更新 UI,无论如何尝试时都会收到 InvalidOperationException。

DataReceived 事件肯定会帮助您避免冻结您的 UI。您的问题中的提示太少,无法知道您的真正问题可能是什么。一个问题可能是过于频繁地使用 Control.BeginInvoke(),导致 UI 线程充斥着调用请求,因此它无法完成其常规职责。就像响应输入和绘画一样。解决方法是减少调用频率,您只需要让人类的眼睛保持愉悦,而且它们的工作速度不会那么快。缓冲接收到的数据,保持 UI 的输出量合理,这样人们实际上可以看到的不仅仅是模糊。

另一个常见问题是deadlock,它将永久冻结您的程序。使用调试器很容易诊断,您会看到您的程序卡在 SerialPort.Close() 调用上。当您使用 Control.Invoke() 而不是 Control.BeginInvoke() 时会发生这种情况。不要使用调用()。

于 2013-07-25T22:42:15.417 回答