我知道.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套接字。