我知道.NET中的SerialPort通信旨在當數據可用並且達到閾值時將DataReceived
事件發送到接收器。SerialPort通信問題
我們不能使用那個DataReceived
事件並在接收端啓動一個線程來頻繁地調用其中一個ReadXXX
方法來獲取數據嗎?
如果接收者比發送者慢得多,會發生什麼? SerialPort緩衝區溢出(數據丟失)?
我知道.NET中的SerialPort通信旨在當數據可用並且達到閾值時將DataReceived
事件發送到接收器。SerialPort通信問題
我們不能使用那個DataReceived
事件並在接收端啓動一個線程來頻繁地調用其中一個ReadXXX
方法來獲取數據嗎?
如果接收者比發送者慢得多,會發生什麼? SerialPort緩衝區溢出(數據丟失)?
這很有效,實際上這是我在我的問題Constantly reading from a serial port with a background thread中使用的方法之一。
對於您的場景,您可以聽DataReceived event
,然後啓動一個線程,在端口上調用ReadExisting
以獲取當前可用的所有字節。您還可以通過查看SerialPort.BytesToRead
屬性來檢查接收緩衝區中有多少個字節正在等待。
至於你的接收緩衝區溢出,a)它足夠大(你可以檢查SerialPort.ReadBufferSize
屬性)和b)這不是1982年,所以CPU的速度足以處理來自端口的數據,沒有時間填滿(當然比串行數據速率快得多)。
這樣做沒什麼意義,只需在打開端口後自己啓動讀取器線程,而不用擔心DataReceived。按照自己的方式進行操作很困難,難以在啓動線程後乾淨地取消訂閱DataReceived事件,尤其是在收到數據時。你不能讓他們都有。
讀取串口可以作爲該線程的功能:
private void ThreadRx()
{
while (true)
{
try
{
if (this._serialPort.IsOpen == true)
{
int count = this._serialPort.BytesToRead;
if (count > 0)
{
byte[] Buffer = new Byte[count];
this._serialPort.Read(Buffer, 0, count);
//To do: Call your reception event (sending the buffer)
}
else
{
Thread.Sleep(50);
}
}
else
{
Thread.Sleep(200);
}
}
catch (ThreadAbortException ex)
{
//this exception is invoked calling the Abort method of the thread to finish the thread
break;//exit from while
}
catch (Exception ex)
{
//To do:call your error event
}
}
}
不要擔心輸入緩衝器,因爲線程能夠比串口通信的波特率讀得更快,你甚至可以使用這個相同的代碼來讀取一個tcp/ip套接字。