【发布时间】:2021-07-31 18:55:31
【问题描述】:
我正在尝试实现某种节拍器(节拍器)逻辑,每次点击一个键,计算每次点击之间的间隔, 测量平均 BPM(每分钟心跳次数)
例如,如果我每秒点击一个键,我希望 BPM 为 60。
我介绍了一些在点击时使用它的代码,我注意到某种延迟,平均为 62,
我认为我的手动点击不正确, 所以我引入了一个 Timer 对象,它会每秒“点击”一次, 而且,我得到了 62 而不是 60 bpm
这是为什么呢?怎样才能更准确?
这是我的代码:
对不起,它是意大利面,我只是为了好玩而尝试它
public class Program
{
static Stopwatch sw = new Stopwatch();
static List<double> nums = new List<double>();
private static void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
EvaluateTime(sw, nums);
sw.Restart();
}
// Driver program
public static void Main()
{
Console.WriteLine("App is ready");
Timer timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.AutoReset = true;
sw.Restart();
timer.Start();
while (true)
{
Console.WriteLine(sw.Elapsed.TotalSeconds);
var x = Console.ReadKey();
if (x.Key != ConsoleKey.B)
{
EvaluateTime(sw, nums);
}
sw.Restart();
if (x.Key == ConsoleKey.S)
{
return;
}
}
}
private static void EvaluateTime(Stopwatch sw, List<double> nums)
{
nums.Add(sw.Elapsed.TotalSeconds);
Console.Clear();
Console.WriteLine($"Average: {Math.Round(60 / (nums.Sum() / nums.Count), 2)}");
}
}
【问题讨论】:
-
为什么每次通过主轮询循环都重新启动
Stopwatch?此外,您似乎没有在任何地方使用Timer实例。 -
@KarlKnechtel,我正在重新启动秒表,因为我对间隔感兴趣,这对我来说与从记录的最后一个滴答声中减去当前滴答声相同。
-
@KarlKnechtel 并启动计时器(并注册到每秒发生的事件)
-
看起来你每秒都会在列表中添加一个项目,然后当你按下 B 以外的任何键时会额外添加一个。这是否意味着你总是会比预期多得到一个?也最好打印总和和计数,以便您/我们可以看到发生了什么。
-
我正在尝试使用\不点击进行测试,而无需点击我只使用计时器。我认为也许不重新启动秒表并实际检查经过的时间与之前的刻度总和会更好