【问题标题】:C# Timer not resetting from one click to anotherC#计时器没有从一次点击重置为另一次点击
【发布时间】:2013-12-14 08:28:43
【问题描述】:

我需要使用 Ticks 存储钢琴持续时间,然后根据该持续时间显示音符(音乐播放器会知道)。

我使用的是 100 的间隔,但对于某些测试,我使用了 1000。

问题是这样的。当我调用该方法时(我正在使用 1000 毫秒间隔一个),计时器开始.. 如果我没有设法获得 1000 毫秒,它会显示 Duration 0: 但如果我这样做了例如 2 秒,它显示 3 秒,如果我尝试再按一秒(不同的键)它会显示 4 秒而不是 1。

就像它不断重复一样。 100 间隔 1 也是如此。它发疯了。有时 40 有时 23 等等。知道如何修复(重置计时器)

注意,我使用 System.Windows.Forms.Timer 作为库

调用下面的方法的方法的一部分

for (int i = 0; i < 15; i++)
{
    WhiteKey wk = new WhiteKey(wKeys[i], wPos[i]-35,0); //create a new white Key with [i] Pitch, at that x position and at y =0 position
    wk.MouseDown += onRightClick; //holds the Duration on Right Click
    wk.MouseUp += onMouseUp;
    wk.Click += new EventHandler(KeyClick); //Go to KeyClick Method whenever a key is pressed
    this.panel1.Controls.Add(wk); //Give it control (to play and edit)
}

控制时间的方法

private void onRightClick(object sender, MouseEventArgs e)
{        
    wk = sender as WhiteKey;
    duration = 0;
    t1.Enabled = true;
    t1.Tick += timeTick;
    t1.Interval = 100; 
}

private void timeTick(object sender, EventArgs e)
{
    duration++;
}

private void onMouseUp (object sender, MouseEventArgs e)
{

    t1.Enabled = false;
    String time = "Key: " + pitch + "\nDuration: " +duration ; //Test purposes to see if timer works
    MessageBox.Show(time);
}

【问题讨论】:

    标签: c# timer


    【解决方案1】:

    你正在尝试测量时间,不要使用 Timer,使用Stopwatch

    你可以找到C# Stopwatch Exmples at dotnetpearls.com

    抽象地说,这就是您想要做的事情:

    private void onRightClick(object sender, MouseEventArgs e)
    {
        stopwatch.Reset();
        stopwatch.Start();
    }
    
    private void onMouseUp (object sender, MouseEventArgs e)
    {
        stopwatch.Stop();
        String msg = "Duration in seconds: " + (stopwatch.ElapsedMilliseconds / 1000.0).ToString("0.00");
        MessageBox.Show(msg);
    }
    

    注意:您可能需要更改单位或字符串格式。


    使用定时器注意事项:

    1) System.Windows.Forms.Timer 使用窗口的消息循环,这意味着它可能会因为窗口忙于处理其他事件(例如单击)而延迟。要获得更好的行为,请使用System.Threading.Timer

    2) 如果使用 System.Windows.Forms.Timer,请不要在每次点击时设置 Tick 事件处理程序。每次添加事件处理程序都会执行一次。

    即:

    private void onRightClick(object sender, MouseEventArgs e)
    {        
        wk = sender as WhiteKey;
        duration = 0;
        t1.Enabled = true;
        //t1.Tick += timeTick; you should add this only once not each click
        t1.Interval = 100;
    }
    

    3) 如果您使用 System.Threading.Timer,您可能需要创建变量 duration volatile

    【讨论】:

    • 我尝试了秒表,效果很好,谢谢。我还会看到 The Timer 的第二种方法。非常感谢您的帮助
    • 另一件事。 Windows.Timers.TIMER - 它如何处理 TICKS,因为它的库中实际上没有它?
    • @DodoSerebro Timer.Tick 是一个事件。在 Timer 内部,它存储了必须调用每个“tick”的方法列表。当您说t1.Tick += timeTick 时,您是在说:“我希望您每次触发事件 Tick 时都调用 timeTick”。现在,Tick 事件通过告诉操作系统以给定的时间间隔发出一条消息(在 Windows 中它是一个 WM_TIMER,请参阅SetTimer),每次窗口收到此消息时,它将运行一个由Timer 对象,依次调用他列表中的所有方法。
    【解决方案2】:
    t1.Tick += timeTick;
    

    顺便说一下,在您的代码示例中,您每次单击鼠标右键都会订阅“Tick”计时器事件。 所以如果你点击 2 次

    private void timeTick(object sender, EventArgs e)
    

    方法将被调用两次,“duration++”将被执行两次。您的事件订阅代码应该只为计时器执行一次。 附言如果您需要测量持续时间,Timer 并不是最好的方法。

    【讨论】:

    • 所以在这种情况下,如果我要使用 t1.Tick += time Tick.. 它应该在哪里?在 onRightClick 方法之外?
    • 谢谢,尽管秒表工作正常,但会尝试一下 :) 再次感谢您的帮助!
    猜你喜欢
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多