我的应用程序通过 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
}
我不明白下一个电报时间戳怎么会比上一个电报时间戳低?
查看我尝试过的代码
穿线。它总是线程。
你读到
DateTime.Now
已经很晚了,另一边却打电话给ThreadPool.QueueUserWorkItem
。
ThreadPool.QueueUserWorkItem
不一定能保证被订购,无论如何你可能会遇到以下情况:
DateTime.Now
)DateTime.Now
如果您关心接收字节的时间,请在执行任何类型的线程分派(
DateTime.Now
、ThreadPool.QueueUserWorkItem
等)之前,在从串行端口读取字节时记录mainWindow.Dispatcher.Invoke
.