【问题标题】:Increment with timer.Tick not working使用计时器递增。Tick 不起作用
【发布时间】:2014-05-17 11:45:02
【问题描述】:

我设置了一个节拍器项目。我有一个点击按钮,它应该检查你的节拍速度并将其平均。因为我用计算器检查了它,所以每一点数学都能正常工作。代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;

namespace Metronome
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer3_Tick(object sender, EventArgs e)
        {
            // Convert tempo to timer1.Tick (miliseconds between each beat)
            timer1.Interval = Convert.ToInt32(60000 / numericUpDown1.Value);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Play / Pause button
            if (button1.Text == "Go!") { timer1.Enabled = true; button1.Text = "Stop!"; }
            else if (button1.Text == "Stop!") { timer1.Enabled = false; button1.Text = "Go!"; }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // The 'ding' sound for the metronome
            SystemSounds.Beep.Play();        
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // Set the tempo to be the average of the convertion from miliseconds between 2 beats and the current tempo
            if (timer2.Enabled) { numericUpDown1.Value = ((60000 / Tap) + numericUpDown1.Value) / 2; Tap = 0; }
            else timer2.Enabled = true;
        }

        int Tap = 0;
        private void timer2_Tick(object sender, EventArgs e)
        {
            // Get the amount of miliseconds between each beat
            Tap++;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // Reset the tap timer
            timer2.Enabled = false;
            Tap = 0;
        }
    }
}

问题出在 timer2_Tick 中,因为它应该每毫秒为 Tap 加 1,而当我尝试它时,它会变成一个很小的数字,例如 20 或 30。我该如何解决这个问题?

【问题讨论】:

  • 定时器没有毫秒分辨率。它的分辨率约为 15 毫秒。这可以解释你得到的价值。
  • 那么我可以将 timer2.Interval 更改为 15 并将 (60000 / Tap) 替换为 (4000 / Tap) 吗?间隔必须尽可能小以防止错误
  • 这可能有效,但不能保证。 Windows 是一个多用户操作系统。其他线程可以中断您的线程的执行,从而有效地延迟计时器引发的滴答事件。您将尽最大努力尝试请求的分辨率。如果你这样做,错误是不可避免的。

标签: c# winforms


【解决方案1】:

在选择要使用的计时器时,我总是依赖一篇非常好的文章:

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

我建议使用线程选项之一。具体来说,文章提到了 Windows 窗体计时器 (System.Windows.Forms.Timer):

如果您正在寻找节拍器,那么您来错地方了。

【讨论】:

  • roryap 是正确的。 SWF.Timer 只会在 UI 线程处于活动状态时触发。你真的很想用System.Threading.Timer (msdn.microsoft.com/en-us/library/swx5easy.aspx)
  • 它有效,但占用了大量代码,所以我改为将其更改为 System.Diagnostics.Stopwatch,这样我就不必花时间弄清楚了。还是谢谢
【解决方案2】:

如果您只需要检查两次按键之间的时间间隔,请使用StopWatch。它为您提供高精度的计时机制。您无需自己计算毫秒数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多