簡體   English   中英

多線程和偵聽串行端口

[英]Multithreading and Listening Serial Port

可以說我要從串行端口接收一些數據。 對serial.ReadLine()使用塊調用並使用以下事件。

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

        string line = port.ReadLine();

            // PROCESS DATA Somewhere else

}

我從不同的來源閱讀,他們都說serial.ReadLine有它自己的線程,除非使用BeginInvoke,否則我不應該從此線程修改UI。 但是,我注意到一段時間后,UI仍然會變得無響應。

所以這是我的問題。 在port_DataReceived內部調用一個新線程是一個壞主意嗎? 我想接收數據並在另一個線程中處理接收到的數據,但是mythread.Start()放在哪里? 我無法一直啟動它,只是希望它知道接收數據后何時獨立運行。 根據MSDN,中止的線程無法再次啟動。 放置Thread.Sleep將凍結我的UI。

您誤解了發生了什么。 SerialPort.ReadLine() 使用一個線程。 是您的DataReceived事件處理程序在另一個線程上運行。 這是必需的,以便SerialPort可以盡快將接收到的數據通知您的代碼,而不必等待UI線程空閑。 這確實意味着您不能直接從事件處理程序中更新UI,無論如何嘗試都將收到InvalidOperationException。

當然,DataReceived事件可以幫助您避免凍結UI。 您的問題中沒有太多提示可以知道您的真正問題是什么。 一個問題可能是過於頻繁地使用Control.BeginInvoke(),在UI線程中充斥着調用請求,因此它無法正常工作。 喜歡回應輸入和繪畫。 解決方法是簡單地減少調用頻率,只需要保持人眼愉悅,它們就不會那么快地工作。 緩沖接收到的數據,使輸出到UI的數量保持合理,這樣人類實際上可以看到的不僅僅是模糊。

另一個常見問題是死鎖 ,它將永久凍結您的程序。 使用調試器易於診斷,您會看到程序卡在SerialPort.Close()調用中。 當您使用Control.Invoke()而不是Control.BeginInvoke()時,會發生這種情況。 不要使用Invoke()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM