等到计时器滴答特定次数

时间:2012-11-10 05:21:58

标签: c#

我试图让我的程序什么都不做,直到我的计时器滴答两次(总共2秒)。 我使用以下代码,除非我取出while语句,否则计时器不会工作。

timer = 0;
Console.WriteLine("timer start ");
timer1.Start();
while (timer < 2);
Console.WriteLine("timer ends");

private void timer1_Tick(object sender, EventArgs e)
{
    Console.WriteLine(timer);
    timer++;
}

2 个答案:

答案 0 :(得分:4)

你应该使用System.Timers.Timer,它将在一个单独的主题中运行,请参阅MSDN article

从上面链接:

System.Windows.Forms.Timer

  

如果您正在寻找节拍器,那么您来错了地方。此计时器类引发的计时器事件与Windows窗体应用程序中的其余代码同步。这意味着正在执行的应用程序代码永远不会被此计时器类的实例抢占(假设您没有调用Application.DoEvents)。

System.Timers.Timer

  

.NET Framework文档将System.Timers.Timer类称为基于服务器的计时器,该计时器是为在多线程环境中使用而设计和优化的。可以从多个线程安全地访问此计时器类的实例。与System.Windows.Forms.Timer不同,System.Timers.Timer类默认情况下将调用从公共语言运行时(CLR)线程池获取的工作线程上的计时器事件处理程序。 这意味着您的Elapsed事件处理程序中的代码必须符合Win32编程的黄金规则:永远不能从用于实例化它的线程以外的任何线程访问控件的实例

工作代码:

public partial class Form1 : Form
{
    System.Timers.Timer  tmr = new System.Timers.Timer(1000);
    volatile int timer;
    public Form1()
    {
        InitializeComponent();

    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        timer = 0;

        tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
        tmr.Start();
        while (timer < 2) ;
        tmr.Stop();
        Console.WriteLine("timer ends");
    }

    void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Console.WriteLine(timer);
        timer++;
    }
}

答案 1 :(得分:3)

不确定您正在使用哪个计时器类(这很重要)。假设它类似于System.Windows.Forms.Timer,则tick永远不会发生,因为它是在主事件循环上调度的,并且你正在用while循环绑定主事件循环。如果它是一个与GUI无关的计时器类,则由于缺少线程同步,可能存在内存可见性问题。

我也很好奇为什么两个蜱?大概这是简化的代码,你的timer_tick方法实际上做了一些更有趣的事情?如果没有,你可以只是Thread.Sleep(2000)。如果刻度代码做了一些有趣的事情,你可以在tick方法中处理完成,如下所示:

timer = 0;
Console.WriteLine("timer start ");
timer1.Start();

private void timer1_Tick(object sender, EventArgs e)
{
    Console.WriteLine(timer);
    if (++timer == 2) {
      Console.WriteLine("timer ends");
      // and you probably want a timer1.Stop() in here too
    }
}