从串行端口获取的绘图数据逐渐变慢

时间:2019-03-17 18:06:32

标签: c# serial-port drawing

我正在研究电压表应用程序,该应用程序绘制电压波形。硬件每秒通过串行端口以字符串格式发送1000个数字(范围为0-1023,始终为整数)。

public SerialPort serialPort = new SerialPort("COM3", 57600);
serialPort.Open();

将字符串转换为int,然后使用DrawLine将其绘制到PictureBox中。

// variable declarations, all is int, runs in its own thread
while (blToMeasure) // true after clicking on button
{
    iPrevY = iY;
    iY = Int16.Parse(serialPort.ReadLine());
    graphicsGraph.DrawLine(penBlack, iX, iPrevY, iX + 1, iY);
    // only this thread is accessing PictureBox
    iX++;

    if (iX > picBoxGraph.Width)
    {
         graphicsGraph.Clear(SystemColors.Control);
         iX = 0;
    }

    if (iY > picBoxGraph.Height)
    {

    }
}

问题在于,画线本身速度很快,只需要几秒钟,但逐渐变慢。

我尝试了Int.ParseInt32.Parse,并使用lock (graphicsGraph)(将带有Clear的条件移动到另一个线程中)或使用BlockingCollection<int>(将DrawLine移到了另一个线程中)以多种方式拆分线程功能,远离Parse)。似乎一无所获,运行一分钟后,应用仍然变慢了几次。

硬件本身没有问题,请使用其他软件进行检查。这对于C#来说太快了吗?

1 个答案:

答案 0 :(得分:0)

解决方案:

使用Port.ReadTimeout = 1Port.DiscardInBuffer()可获得最佳结果。也使用Form.DoubleBuffered = true,但在这种情况下并没有太大的区别。

// constructor
Port.ReadTimeout = 1;
Form.DoubleBuffered = true;

这是循环本身:

btn.Click() // click to start measuring
{
    Port.DiscardInBuffer();
    blToMeasure = true;
}

while (blToMeasure) // true after clicking on button
{
    iPrevY = iY;
    try {
        iY = Int16.Parse(serialPort.ReadLine());
    }
    catch
    {
        // exception logic
    }
    graphicsGraph.DrawLine(penBlack, iX, iPrevY, iX + 1, iY);
    // only this thread is accessing PictureBox
    iX++;

    if (iX > picBoxGraph.Width)
    {
         graphicsGraph.Clear(SystemColors.Control);
         iX = 0;
    }

    if (iY > picBoxGraph.Height)
    {

    }
}

当应用程序开始从端口读取数据时,总是有累积的数据,因为我的硬件一直在发送数字,所以我摆脱了缓冲区。比绘制线条不会以不同的尖峰执行,并且速度是恒定的。通过分析Watch的问题,我发现,读取该数据有时会花费更长的时间,并且由于每秒读取1000次,因此速度变慢。因此,为了避免速度变慢,我使用了Port.ReadTimeout,如果读取时间太长,则会跳过读取。

差异是显而易见的,绘画不再减慢速度,并且与我尝试的时间保持几分钟的相同速度。我认为这是解决我问题的足够方法,谢谢!