在Windows窗体应用程序中使用计时器

时间:2017-12-20 09:42:45

标签: c# winforms timer

我是编码新手并遇到麻烦。

我想使用一个在按下ScatterMode选项卡时启动的计时器,它将在运行“Dosomething”功能之前开始计数4秒。这个循环将重复,直到我决定停止该程序。但我得到的问题是,这个代码只能像2loop一样正确运行,之后计时器会变得疯狂LOL。

     System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

    //ScatterMode Tab
    private void Scatter_modeToolStripMenuItem_Click(object sender, EventArgs e)
    {
            timer.Interval = 4000;
            timer.Enabled = true;
            timer.Tick += new EventHandler(Dosomething);
            timer.Start();
    }

    private void Dosomething (object sender, EventArgs e)
    {
        timer.Stop();
        timer.Enabled = false;

        Grab.buffer(out buffer, out status, 6000);
        Scatter_mode(buffer);
        pictureBox1.Refresh();

        int done_grab = 1;

        if (doneGrab == 1)
        {
            timer.Interval = 4000;
            timer.Enabled = true;
            timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click);
            timer.Start();
            done_grab = 0;
        }
    }

1 个答案:

答案 0 :(得分:3)

为计时器添加一个新的事件处理程序,以处理它的tick事件,在tick事件的处理程序中确实会导致计时器“疯狂”。每次定时器引发其事件时,都会添加另一个事件处理程序(响应引发的事件)。这意味着下次计时器滴答时,事件代码将运行两次。将添加两个新的事件处理程序。下次计时器滴答时,代码将运行4次。将添加4个事件处理程序......依此类推

从代码中删除此行:

timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click);

将此行移动到表单的构造函数中:

timer.Tick += new EventHandler(Dosomething);

您只想将此事件处理程序连接一次。每次计时器的间隔过去,代码将运行一次:)

我还会对您的代码进行一些同行评审,请参阅评论:

 System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

//ScatterMode Tab
private void Scatter_modeToolStripMenuItem_Click(object sender, EventArgs e)
{
        timer.Interval = 4000; //can go in the constructor also; don't need to set repeatedly
        timer.Enabled = true;
        timer.Tick += new EventHandler(Dosomething); //move to constructor
        timer.Start(); //this isn't needed - you already Enabled the timer, which started it
}

private void Dosomething (object sender, EventArgs e)
{
    timer.Stop();          //use this
    timer.Enabled = false; //or this. It's not required to do both

    Grab.buffer(out buffer, out status, 6000);  //if these lines crash then your timer will
    Scatter_mode(buffer);                       //only restart if the toolstripmenuitemclick
    pictureBox1.Refresh();                      //above runs.. is it what you wanted?

    int done_grab = 1; //not needed

    if (doneGrab == 1) //this will always evaluate to true, it is not needed
    {
        timer.Interval = 4000; //the interval is already 4000, not needed
        timer.Enabled = true; //careful; your timer may stop forever if the code above crashes
        timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click); //remove
        timer.Start(); //not needed
        done_grab = 0; //not needed
    }
}