需要一种替代方法来获得20毫秒的分辨率周期

时间:2015-11-03 14:38:17

标签: c# .net timer

我需要每隔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我的处理器会陷入无限循环。所以这个操作需要它自己独立的线程,它始终有效(使用处理器)。是否有更专业的方式来做这件事。请建议。我需要在一个单独的线程中运行这个应用程序,因为它必须在应用程序启动后立即运行,直到它关闭。

5 个答案:

答案 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添加一些其他技巧:

  1. 请求高计时器分辨率:MSDN: Obtaining and Setting Timer Resolution。您可以在pinvoke.net上找到C#签名

  2. 使用Stopwatch类计算等待期的长度。如果周期小于1毫秒,请不要打电话给睡眠。

  3. 使用Thread

  4. 增加线程优先级
  5. 如果可能的话,在另一个线程上进行昂贵的计算。

  6. 可选:在Thread.Sleep之后使用忙等待最多1 ms以获得更好的精确度。使用Thread.SpinWait。

  7. 结合1.和2.给了我足够的精确度来实现游戏的帧制动,而不会造成口吃/滞后。