我需要每隔CAN
阅读来自20ms
网络的邮件。为此我创建了一个功能,其定义如下。这是一种解决方法,但能完成这项工作。
public void Read_CAN_RC_Message()
{
bool a = true;
while (a)
{
Stopwatch t = Stopwatch.StartNew();
// My actual Function Starts Here
int rMulti = CANbus.CAN_Receive_multiple_nonblock(recieveMsg, 5);
if (0 < rMulti)
{
count++;
for (int k = 0; k < rMulti; k++)
{
if (recieveMsg[k].id == 0x400)
{
currentX = 0;
currentY = 0;
currentX = currentX | recieveMsg[k].data[3];
currentX = (currentX << 8) | recieveMsg[k].data[2];
currentX = (currentX << 8) | recieveMsg[k].data[1];
currentX = (currentX << 8) | recieveMsg[k].data[0];
currentY = currentY | recieveMsg[k].data[7];
currentY = (currentY << 8) | recieveMsg[k].data[6];
currentY = (currentY << 8) | recieveMsg[k].data[5];
currentY = (currentY << 8) | recieveMsg[k].data[4];
}
// Function Ends here
int timestep = t.Elapsed.Milliseconds; // To measure Time Needded to complete the Operation
timeCheck.Rows.Add(timestep,str);
}
while (t.Elapsed < timer20ms)
{
// Nothing
}
}
}
我很快意识到操作需要2ms
才能完成,剩下的18ms
我的处理器会陷入无限循环。所以这个操作需要它自己独立的线程,它始终有效(使用处理器)。是否有更专业的方式来做这件事。请建议。我需要在一个单独的线程中运行这个应用程序,因为它必须在应用程序启动后立即运行,直到它关闭。
答案 0 :(得分:2)
使用Timer类。你可以每20ms调用一次你的函数。
https://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx
答案 1 :(得分:1)
您可以使用具有20ms Timer_Elpased的定时器。或者您可以将线程置于睡眠模式15-20毫秒。 Thread.sleep代码(20)
答案 2 :(得分:0)
我在其他网站找到了解决方案。我正在放置链接,我已经测试了这个,它的工作效果令人惊讶 http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer 希望它能在未来帮助人们。感谢你的帮助。非常感谢。 @idstam感谢您发送MSDN链接。它教了我一两件事。
答案 3 :(得分:0)
如果设备定期发送数据,则必须使用异步方式获取数据。
为了向您提供完整的解决方案或建议,请显示CANbus dll的完整合同。
如果你解释了主要任务,也会更好。
答案 4 :(得分:0)
我建议Thread.Sleep
添加一些其他技巧:
请求高计时器分辨率:MSDN: Obtaining and Setting Timer Resolution。您可以在pinvoke.net上找到C#签名
使用Stopwatch
类计算等待期的长度。如果周期小于1毫秒,请不要打电话给睡眠。
使用Thread
类
如果可能的话,在另一个线程上进行昂贵的计算。
可选:在Thread.Sleep之后使用忙等待最多1 ms以获得更好的精确度。使用Thread.SpinWait。
结合1.和2.给了我足够的精确度来实现游戏的帧制动,而不会造成口吃/滞后。