【问题标题】:Timer won't tick计时器不会滴答作响
【发布时间】:2012-11-16 07:23:26
【问题描述】:

我的代码中有一个Windows.Forms.Timer,我正在执行 3 次。但是,计时器根本没有调用 tick 函数。

private int count = 3;
private timer;
void Loopy(int times)
{
    count = times;
    timer = new Timer();
    timer.Interval = 1000;
    timer.Tick += new EventHandler(timer_Tick);
    timer.Start();
}

void timer_Tick(object sender, EventArgs e)
{
    count--;
    if (count == 0) timer.Stop();
    else
    {
        // Do something here
    }
}

Loopy() 正在从代码中的其他位置调用。

【问题讨论】:

  • 你从哪里调用 Loopy?
  • Loopy() 正在从代码中的另一个位置调用。
  • 从其他地方调用它会覆盖当前的计时器对象。有你的问题。
  • 您如何验证计时器没有计时?你在哪里调用 Loopy 函数?最好提供一个最小但完整的示例来说明问题。到时候你很可能会自己解决。
  • 这段代码很好用。问题出在您未显示的代码中的其他地方。

标签: c# forms timer


【解决方案1】:

尝试使用 System.Timers 而不是 Windows.Forms.Timer

void Loopy(int times)
{
    count = times;
    timer = new Timer(1000);
    timer.Enabled = true;
    timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    timer.Start();
}

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    throw new NotImplementedException();
}

【讨论】:

  • 我真的不清楚这如何解决问题。行为完全相同(但我也无法重现原始问题)。
  • @jeroenh 我完全同意。
  • @mrfishie 你还能通过恢复到 Windows.Forms.Timer 来重现原来的问题吗?
  • Windows.Forms.Timer 在控制台应用程序中或在表单外使用时不起作用。
  • @mrfishie 您是否在您的应用程序中做任何其他可能占用主线程的工作?还可以尝试将 System.Timer 的 SynchronizingObject 设置为 this 并查看问题是否再次出现。
【解决方案2】:

如果在不是主 UI 线程的线程中调用 Loopy() 方法,则计时器不会计时。 如果您想从代码中的任何位置调用此方法,则需要检查InvokeRequired 属性。所以你的代码应该是这样的(假设代码是一个表单):

        private void Loopy(int times)
        {
            if (this.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    Loopy(times);
                });
            }
            else
            {
                count = times;
                timer = new Timer();
                timer.Interval = 1000;
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
        }

【讨论】:

    【解决方案3】:

    我不确定你做错了什么,它看起来是正确的,这个代码有效:看看它与你的比较。

    public partial class Form1 : Form
    {
        private int count = 3;
        private Timer  timer;
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            Loopy(count);
        }
    
        void Loopy(int times)
        {
            count = times;
            timer = new Timer();
            timer.Interval = 1000;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }
    
        void timer_Tick(object sender, EventArgs e)
        {
            count--;
            if (count == 0) timer.Stop();
            else
            {
                //
            }
        } 
    
    }
    

    【讨论】:

      【解决方案4】:

      这是一个有效的Rx 代码:

      Observable.Interval(TimeSpan.FromSeconds(1))
      .Take(3)
      .Subscribe(x=>Console.WriteLine("tick"));
      

      当然,您可以在您的程序中订阅更有用的内容。

      【讨论】:

      • 真的这是最好的答案。每当我看到显式添加或删除事件处理程序时,我都会寻找一个预烘焙的 RX 解决方案或编写一个扩展方法来包装事件处理。请注意, Take(3) 不仅处理三个样本,它还处理事件处理程序,因此您不会泄漏内存。以上所有解决方案都忘记在获取事件后移除事件处理程序。
      【解决方案5】:

      如果您使用的是 Windows.Forms.Timer,则应使用以下内容。

      //Declare Timer
      private Timer _timer= new Timer();
      
      void Loopy(int _time)
      {
      
          _timer.Interval = _time;
          _timer.Enabled = true;
          _timer.Tick += new EventHandler(timer_Elapsed);
          _timer.Start();
      }
      
      void timer_Elapsed(object sender, EventArgs e)
      {
          //Do your stuffs here
      }
      

      【讨论】:

        【解决方案6】:

        检查您的属性中的计时器是否已启用。 我的是假的,设置为真后它起作用了。

        【讨论】:

        • 应该无关紧要,因为定时器是通过 timer.Start() 启动的,它在功能上与启用控件相同。
        【解决方案7】:

        如果你使用一些小于定时器内部间隔的延迟,system.timer 将执行其他线程,你必须处理同时运行的双线程。应用 InvokeRequired 来控制流程。

        【讨论】:

        • 欢迎来到 SO!请提供实现您的解决方案的代码示例,因为您当前的答案不是很有帮助。另请参阅How to answer questions
        【解决方案8】:

        您可能已经从另一个线程启动了计时器,因此请尝试从正确的线程调用它。 例如,而不是:

        timerX.start();
        

        用途:

        Invoke((MethodInvoker)delegate { timerX.Start(); });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-27
          • 1970-01-01
          • 1970-01-01
          • 2018-01-09
          • 2011-09-19
          相关资源
          最近更新 更多