【问题标题】:Elapsed time is not giving me expected result经过的时间没有给我预期的结果
【发布时间】:2013-05-25 14:37:26
【问题描述】:

我每隔几秒就会收到一个包含“1”的字符串。我正在尝试获取接收到的字符串和下一个字符串之间的经过时间以返回经过的时间。我做错了什么。我得到的结果是 0,而字符串每秒更新一次,所以我应该读 1。我很确定逻辑中有错误,但我看不到它在哪里。这应该运行几个小时并在每次我得到字符串“giriRicevuti”的更新时更新。

class Rpm
{
    public void CalcolaRPM(string giriRicevuti, out long RPM)
    {
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        if (giriRicevuti == "1")
        {
            stopWatch.Stop();
        }
            long duration = stopWatch.ElapsedMilliseconds;

            RPM =(duration/1000);
    }
}

【问题讨论】:

  • 什么时候调用该方法?
  • 您的方法启动秒表,然后立即测量秒表已经运行了多长时间——这显然不是很长时间,因为您刚刚启动了秒表。
  • @dtb,当我得到下一个“1”时应该停止。这就是我想要达到的目标。我已经设置了停止的条件。但显然不起作用。
  • @BernhardPoiss 每次我从串口收到一条包含“1”的消息。
  • 使用 Equals 方法进行比较。 string.stackoverflow.com/questions/1659097/c-string-equals-vs

标签: c# elapsedtime


【解决方案1】:

如果您想对 inbetween 调用它的时间进行计时,则需要在 CalcolaRPM() 方法之外放置一个秒表。

最简单的做法是将其添加为类中的私有字段。

另一个问题是,当giriRicevuti 不是“1”时,您需要返回最后一个已知的 RPM - 我们也可以通过将最后一个已知的 RPM 保存在私有字段中来解决这个问题。

还有一个问题是,第一次计算 RPM 时,它不可能准确,因为没有之前的时间来比较它。我们将通过返回-1 来解决此问题,直到我们有正确的报告时间。

接下来,您将经过的 RPM 计算为整数计算。现在想象一下,如果事情稍微有点不对劲,那么经过的时间总是 999 毫秒。只有一毫秒,但您计算的 RPM = 999/1000 将导致零。

您有多种选择,但最有可能的是:

  • 改为返回双精度值。
  • 将该值四舍五入到最接近的 RPM。

我去了四舍五入。 RPM 计算不正确,因此我同时更正:

lastRPM = (int) Math.Round(60000.0/((int) stopWatch.ElapsedMilliseconds));

总而言之,这是一个可编译的测试程序(控制台应用程序):

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;

namespace Demo
{
    class Rpm
    {
        private Stopwatch stopWatch = new Stopwatch();
        private int lastRPM = -1;

        // RPM will be -1 until we have received two "1"s       

        public int CalcolaRPM(string giriRicevuti)
        {
            if (giriRicevuti == "1")
            {
                if (stopWatch.IsRunning)
                    lastRPM = (int) Math.Round(60000.0/((int) stopWatch.ElapsedMilliseconds));

                stopWatch.Restart();
            }

            return lastRPM;
        }
    }

    class Program
    {
        void run()
        {
            test(900);
            test(1000);
            test(1100);
            test(500);
            test(200);
        }

        void test(int interval)
        {
            Rpm rpm = new Rpm();

            for (int i = 0; i < 10; ++i)
            {
                Thread.Sleep(interval);
                rpm.CalcolaRPM("0");
                rpm.CalcolaRPM("1").Print();
                rpm.CalcolaRPM("2");
            }
        }

        static void Main()
        {
            new Program().run();
        }
    }

    static class DemoUtil
    {
        public static void Print(this object self)
        {
            Console.WriteLine(self);
        }

        public static void Print(this string self)
        {
            Console.WriteLine(self);
        }

        public static void Print<T>(this IEnumerable<T> self)
        {
            foreach (var item in self) Console.WriteLine(item);
        }
    }
}

【讨论】:

  • 由于秒表是在任意时间启动的,因此初始计算往往不准确。
  • 我想我们应该在第一次计算时返回 -1,因为那总是不准确的。我会更新的。
  • @MatthewWatson,谢谢,但即使字符串 giriRicevuti 每 1 秒更新一次,RPM 仍然为 0。我已经用断点检查了它。此外,我对传入的串行消息有一个过滤器,它检测到“1”并将其传递给此方法,因此没有其他类型的值传递给它。
  • @FeliceM 我还有最后一个问题要解决,哈哈。 :) 我现在正在更新,等几分钟
  • @HABO,我需要测量以每分钟 5 到 10 转的速度运行的电机的 RPM。应该不是问题。
【解决方案2】:

感谢您的 cmets 和建议,我最终得到了这个解决方案。我还使用返回和一些浮动变量简化了该方法,以获得更高的准确性。 这个适用于我的应用程序。

class Turns
{
    static DateTime prevTimeInstance = DateTime.Now;
    static float RPM = 0;

    public float Counts(int getTurn)
    {
        TimeSpan currentTimeSpan = TimeSpan.Zero;
        if (getTurn.Equals(1))
        {
            currentTimeSpan = DateTime.Now.Subtract(prevTimeInstance);
            prevTimeInstance = DateTime.Now;
            if (currentTimeSpan.TotalSeconds != 0)
                RPM = 60.0f / (float)currentTimeSpan.TotalSeconds;
        }
        return RPM;
    }
}

我要感谢 Mattew 给予我的大力帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    相关资源
    最近更新 更多