2012-11-10 30 views
3

我试图让我的程序不做任何事,直到我的计时器滴答两次(总共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++; 
} 

回答

3

不知道你正在使用什么计时器类(这很重要)。假设它是类似System.Windows.Forms.Timer的东西,tick不会发生,因为它是在主事件循环中调度的,而且你正在用while循环捆绑主事件循环。如果它是一个不依赖于GUI的计时器类,则可能由于缺少线程同步而导致内存可见性问题。

我也很好奇为什么两个蜱?据推测这是简化的代码,你的timer_tick方法实际上是在做一些更有趣的事情?如果没有,你可以只是Thread.Sleep(2000)。如果蜱代码做一些有趣的事情,你可以在你打勾的方法处理完成,像这样:

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 
    } 
} 
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

好,翔实的答案,但我建议你把一些锁定周围的访问'timer'变量存储可见性。或者使用'volatile'关键字。 – adv12

+0

@ adv12你是对的,谢谢 –

+0

Still Mark,你为什么不同步这些线程?你知道,'Monitor.Wait',而不是常量计时器检查... – neeKo