DateTime.Now 随着时间的推移是否不一致?

问题描述 投票:0回答:1

我的应用程序通过 UART 从总线记录电报。对于每封电报,我都会在接待处添加带有 DateTime.Now 的时间戳。现在我有这样的现象,有时下一个电报时间戳比之前的要低 100 毫秒。这太令人困惑了。

这是怎么发生的?我该如何预防?

这是我的代码:

private SerialPort port;

public void RegisterReceive()
        {
            ...
            port.DiscardOutBuffer();
            port.DiscardInBuffer();
            port.DataReceived += OnReceive;
            ....
        }

public static Mutex mutexReceivingCom = new Mutex();
        void OnReceive(object sender, SerialDataReceivedEventArgs args)
        {
            SerialPort port = sender as SerialPort;

            mutexReceivingCom.WaitOne();   // Wait until it is safe to enter. 

            if (data.AppIsRunning)
            {
                Byte by;
                try
                {
                    while (port.BytesToRead > 0)
                    {
                        by = (Byte)port.ReadByte();
                        mainWindow.Dispatcher.Invoke(() =>
                        {
                            General_HandleTelegram.Add_HandleTeleData_ByteToUartInBuffer(by);
                        });
                    }


                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show("SerialPort OnReceive Exception: " + ex.ToString());
                    //put other, more interesting error handling here.
                }
            }

            mutexReceivingCom.ReleaseMutex();    // Release the Mutex.

            ThreadPool.QueueUserWorkItem(handleReceivedBytes);
        }

private void handleReceivedBytes(object state)
        {
            mutexReceivingCom.WaitOne();   // Wait until it is safe to enter. 

            if (data.AppIsRunning)
            {
                try
                {
                    BusAnswerOrCyclic_Handling tempPack = null;

                    if (port.IsOpen)
                    {
                        tempPack = ReceiveTelegram(LastRecTelegramm, this);

                        while (tempPack != null)
                        {
                            mainWindow.Dispatcher.Invoke(() =>
                            {
                                if (tempPack != null)
                                    tempPack.ProcessBusTelegram();
                            });

                            if (tempPack != null)
                            {
                                LastRecTelegramm = tempPack;
                            }

                            if (port.IsOpen)
                            {
                                tempPack = ReceiveTelegram(LastRecTelegramm, this);
                            }
                            else
                                break;
                        }

                    }

                    CheckIfBufferCanBeReset();
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show("Error ComPort.cs handleReceivedBytes: " + ex.Message);
                }

            }

            mutexReceivingCom.ReleaseMutex();    // Release the Mutex.
        }


然后

public BusAnswerOrCyclic_Handling ReceiveTelegram(BusAnswerOrCyclic_Handling parLastSendBusTelegram, ComPort comPort)
        {
...
pack= new BusAnswerOrCyclic_Handling(recState, CmdToAssignToReceivedTele, LastSendBusTelegram, fetchedByteList.ToArray(), Generic_HandleTelegrams.mainWindow, comPort, -1, ucTelTyp == enTelTyp.SynLine, true);
....

return pack;
        }


public BusAnswerOrCyclic_Handling(enRecStates recState, BusTelegram_Command command, BusAnswerOrCyclic_Handling LastBusTelegram, byte[] bytes, MainWindow mainWindow, 
            ComPort comPort, short iMasterByteCountWithCRC, bool isSynLine, bool isFullyReceived)
        {
            DateTime dt = DateTime.Now;
...
        }

同时

public void ProcessBusTelegram()
        {
           // adds it to the datalog

        }

我不明白下一个电报时间戳怎么会比上一个电报时间戳低?

查看我尝试过的代码

c# wpf uart
1个回答
1
投票

穿线。它总是线程。

你读到

DateTime.Now
已经很晚了,另一边却打电话给
ThreadPool.QueueUserWorkItem

ThreadPool.QueueUserWorkItem
不一定能保证被订购,无论如何你可能会遇到以下情况:

  1. 您将消息 A 放入队列,然后将消息 B 放入队列
  2. 线程 1 获取消息 A,然后被调度程序暂停
  3. 线程 2 获取消息 B 并运行至完成(正在阅读
    DateTime.Now
  4. 线程 1 恢复,并显示
    DateTime.Now

如果您关心接收字节的时间,请在执行任何类型的线程分派(

DateTime.Now
ThreadPool.QueueUserWorkItem
等)之前,在从串行端口读取字节时记录
mainWindow.Dispatcher.Invoke
.

© www.soinside.com 2019 - 2024. All rights reserved.