我有一个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间隔并且更长的内容? 我应该一起使用不同的计时器吗?
答案 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和我的同事