时序在串行通信中下降

时间:2013-08-14 16:09:46

标签: c# wpf multithreading serial-port

我有一个WPF应用程序,它运行RS232串行通信,我正在编写以替换旧的(光头写的)Borland C ++ dos可执行文件。

在我的应用程序中,为了使UI与通信分开,我在它自己的线程上运行序列。我每30ms发送一次消息给连接的设备。我已经设置了一个SerialDataReceivedEventHandler来捕获任何收到的消息。

    public override void DataRecieved()
    {
        _serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
    }

    public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        queue.Enqueue(((SerialPort)sender).ReadExisting());
    }

在接收到的处理程序中,我对收到的消息进行排队,并在另一个线程中执行我想要的操作。

我的问题是当我在串行通信线路上放置一个示波器时,我看到我的大部分数据包都是以30ms的间隔发出,但有些是40ms。收到的消息在40ms时没有与这些输出消息对齐。

我使用System.Timers.Timer将时间间隔设置为30ms,并且只在ElapsedEventHandler上发送三个字节。

        // Initialize and Start timer
        timer = new Timer(30);
        timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
        timer.Start();


    private void Timer_Elapsed(object source, ElapsedEventArgs e)
    {
        lock(lockObject)
        {
            // Write
            byte[] _buffer = { byte1};
            WriteBuffer(_buffer);


            // Write
            byte[] _buffer1 = { byte2 };
            WriteBuffer(_buffer1);


            // Write
            byte[] _buffer2 = { byte3};
            WriteBuffer(_buffer2);
        }
    }

System.Timers.Timer中是否存在错过30ms间隔并且更长的内容? 我应该一起使用不同的计时器吗?

1 个答案:

答案 0 :(得分:0)

我明白了。我在Stopwatch.ElapsedMilliseconds属性中使用StopWatch。当我的经历时间大于或等于30毫秒时,我发送信息。

        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        while (!Stopped)
        {
            // Loop here. 
            // Received Event handler is capturing messages.

            // Wait 30ms between commands
            if (stopWatch.ElapsedMilliseconds >= 33)
            {
                lock (lockObject)
                {
                    // Write 
                    byte[] _buffer = { byte1, byte2, byte2 };
                    WriteBuffer(_buffer);
                }

                stopWatch.Reset();
                stopWatch.Start();
            }
        }

当我有计时器时

while (!Stopped)
{
     // Loop here. 
     // Received Event handler is capturing messages.
     // Timer is sending messages
}

这对定时器或延迟(System.Threading.Thread.Sleep(30))起作用的原因是我放弃了我的线程到Windows事件处理程序。意思是我在等Windows告诉我可以继续。我没有控制我的线程。

现在使用StopWatch并不完美,但它比Timer更接近,大约32-33ms

谢谢 - @ 500 - 内部服务器错误,@ Peter Ritchie和我的同事