【问题标题】:Property of { return 60000 / bpm } always returning 600ms?{ return 60000 / bpm } 的属性总是返回 600 毫秒?
【发布时间】:2018-08-19 07:58:13
【问题描述】:

我正在尝试构建一个稳定的节拍器,让每个节拍都滴答作响,但似乎有问题。

节拍器等待每个节拍的时间由以下公式确定:60000 / BPM

但是,无论您将什么值插入 BPM,该值似乎都会返回一个特定的数字。

我有一个属性可以返回这个公式的值以及一个 bpm 整数:

static private int bpm = 125;
static private int BeatLength
{
    get
    {
        return 60000 / bpm;
    }
}

static public int beat = 0;

这是负责节拍器的函数(它在专用线程上运行):

public static void RhythmUpdate()
{
    lock (threadLock)
    {
        while (true)
        {
            Thread.Sleep(BeatLength); // Sleep until the next beat
            AddRequest(BeatLength * beat);
            beat++; 
            DefaultSounds.def_CowBell.Play();
            OnBeat?.Invoke();
        }
    }
}

在对def_CowBell.Play(); 设置断点时,Visual Studio 注意到循环大约需要 600 毫秒。这就是我知道价值的方式。

额外信息:

  • 我正在使用 OpenGL

  • 如果被问到可能会更多......

提前感谢您的帮助。

【问题讨论】:

  • Windows 不是 RTOS,您的 Thread.Sleep 所用的时间可能比您要求的要长。 BeatLength 的值是多少?不过,不应该有 120 毫秒的差异。
  • 它在 600ms - 616ms 之间变化很小,但对于属性本身的确切值,我认为它是 600。但我不太使用 VS 暂停功能,所以它可能是我看错了号码。
  • 使用Timer - 很可能该循环中的其他所有内容都在您的睡眠呼叫之上占用了恒定数量。所以你的 thread.sleep 需要 200-400ms 加上另一个,比如循环的其余部分需要 300ms。因此,即使您改变 bpm,循环也不会发生太大变化。
  • 我每拍都记录了 BeatLength 属性,无论如何它都显示 600,所以它返回 600。另外,Ian,我会试试的。
  • Sleep 不会延迟您请求的确切时间,有时可能更短,也可能更长。它基于系统时钟的限制。请参阅备注this post 下的第一段。

标签: c# multithreading properties wait metronome


【解决方案1】:

事实证明,我一直在为一个函数设置 BPM,每当我对其初始化进行更改时,它都会被新的 BPM 覆盖。

public static void StartBeat(int startingBPM)
{
    rhythmThread = new Thread(new ThreadStart(RhythmUpdate)); // Initialize new thread
    bpm = startingBPM; // < This piece of codde was the source.
    rhythmThread.Name = "BeatThread";
    rhythmThread.Start(); // Start the thread
}

现在,我将在测试时禁用该行代码。

【讨论】:

  • 如果你希望它精确,你还应该计算自上次节拍以来的时间,而不是单独依赖Thread.Sleep
猜你喜欢
  • 2014-07-20
  • 1970-01-01
  • 2020-01-07
  • 2021-04-02
  • 1970-01-01
  • 2017-12-29
  • 2013-07-13
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多