SerialPort DataReceived事件使通信更慢

时间:2016-05-11 05:16:29

标签: c# .net windows event-handling serial-port

我正在研究.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;
}

0 个答案:

没有答案