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

本文关键字:20毫 周期 分辨率 方法 一种 | 更新日期: 2023-09-27 18:20:32

我需要在每个20ms读取来自CAN网络的消息。为此,我制作了一个函数,其工作原理如下所述。这是一种变通办法,但确实有效。

    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,我的处理器陷入了无限循环。因此,此操作需要其自己的独立线程,该线程始终可以工作(使用处理器)。有没有一种更整洁、更专业的方法可以做到这一点。请提出建议。我需要在一个单独的线程中运行这个应用程序,因为它必须始终在应用程序启动后运行,直到关闭。

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

使用Timer类。你可以让它每20ms调用你的函数。

https://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx

您可以将Timer与20ms Timer_Elpased一起使用。或者你可以让你的线程处于睡眠模式15-20毫秒。线程睡眠(20)

我在其他网站上找到了一个解决方案。我正在放置链接,我已经测试过了,它的效果非常好http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer希望它将来能帮助人们。谢谢你的帮助。真的很感激@idstam谢谢你给我发MSDN链接。它教会了我一两件事。

在设备定期发送数据的情况下,必须使用异步方式来获取数据。

要为您提供完整的解决方案或建议,请显示CANbus dll的完整合同。

此外,如果你解释一下主要任务会更好。

我推荐Thread.Sleep和一些额外的技巧:

  1. 请求高计时器分辨率:MSDN:获取和设置计时器分辨率。你可能可以在pinvoke.net 上找到C#签名

  2. 使用Stopwatch类来计算等待期的长度。如果周期小于1ms,请不要呼叫"睡眠"。

  3. 使用Thread类提高线程优先级

  4. 如果可能的话,在另一个线程上进行昂贵的计算。

  5. 可选:线程后使用忙等待。睡眠最长1毫秒以获得更好的价格。使用Thread.Spin等待。

组合用1。和2。给了我足够的精度,可以在不造成卡顿/滞后的情况下为游戏执行帧制动。