我正在研究.NET 3.5上的Windows串口通信应用程序。出于传统目的,我不能使用任何其他.NET版本。
我需要将一些数据发送到某个设备,等待查看是否有特定时间段内的数据。如果有数据,我需要处理它。如果在给定时间内没有数据,则无需处理任何事情。
我的第一种等待数据的方法是基于计时器:
[代码1]
using (System.Timers.Timer timer = new System.Timers.Timer(nDefaultWait))
{
bool timeout = false;
timer.AutoReset = false;
timer.Elapsed += (s, e) => { timeout = true; };
int nTotalRead = 0;
do
{
timeout = false;
timer.Start();
while (!timeout && sp.BytesToRead + nTotalRead < nExpectedBytes)
;
timer.Stop();
if (sp.BytesToRead == 0)
{
// No data received for a time period, consider timed out
break;
}
byte[] inBuffer = ReadSerialPort(sp);
receivedBytes.AddRange(inBuffer);
nTotalRead += inBuffer.Length;
} while (receivedBytes.Count < nExpectedBytes);
由于它受CPU限制,因此会降低速度慢的计算机的速度。我正在尝试使用DataReceived事件处理程序修改代码:
[代码2]
nTotalRead = 0;
nExpectedBytes = nExpBytes;
do
{
allDataRead.Reset(); // allDataRead is a ManualResetEvent which is Set from DateReceived event
allDataRead.WaitOne(nDefaultWait);
if (sp.BytesToRead == 0)
{
// No data received for a time period, consider timed out
break;
}
byte[] inBuffer = ReadSerialPort(sp);
receivedBytes.AddRange(inBuffer);
nTotalRead += inBuffer.Length;
} while (receivedBytes.Count < nExpBytes);
DataReceived事件如下所示:
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (serialPort.BytesToRead + nTotalRead >= nExpectedBytes)
{
allDataRead.Set();
}
}
相同的代码用于2个不同的设备(比如A型和B型)进行通信。两种设备都遵循相同的协议。但他们有不同的Windows驱动程序。
性能是强制性要求。一组命令需要尽快完成执行。代码1和代码2对于A类设备几乎完全相同。但是,令我惊讶的是B型设备,Code 2的速度要慢100x-150x(50 ms vs 7500 ms)。不仅如此,对于B类设备,代码2的性能并不一致。有时它在3000毫秒内完成(代码1在50毫秒内始终如一地完成),有时则在10000毫秒或其间的任何地方完成。
这背后可能是什么原因?
修改
以下是ReadSerialPort
的代码:
private byte[] ReadSerialPort(SerialPort sp)
{
byte[] inBuffer = new byte[sp.BytesToRead];
sp.Read(inBuffer, 0, inBuffer.Length);
return inBuffer;
}