【问题标题】:How to add delay inside a for-loop using timers如何使用计时器在 for 循环中添加延迟
【发布时间】:2013-01-17 09:25:36
【问题描述】:

如下代码(timer2的间隔为1000)

private void timer1_Tick(object sender, EventArgs e) {
    timer7.Enabled=false;
    timer8.Enabled=false;
    lblTimer_Value_InBuildings.Text="0";
}

private void timer2_Tick(object sender, EventArgs e) {
    lblTimer_Value_InBuildings.Text=(int.Parse(lblTimer_Value_InBuildings.Text)+1).ToString();
}

我们不能在 for 循环中创建延迟

for(int i=1; i<=Max_Step; i++) { 
    // my code... 

    // I want delay here: 
    timer1.Interval=60000; 
    timer1.Enabled=true; 
    timer2.Enabled=true; 

    // Thread.Sleep(60000); // makes no change even if uncommenting
}

无论我是否取消注释 Thread.Sleep(60000); 行,我们都看到 lblTimer_Value_InBuildingstimer2_Tick 中没有任何变化。

你能给我一个解决方案吗(带或不带计时器)?

【问题讨论】:

    标签: c# timer sleep windows-applications


    【解决方案1】:

    当您执行 Thread.Sleep(60000) 时,您是在告诉 UI 线程休眠 60 秒。这也会阻止定时器的执行,因为 UI 线程挂起休眠而不是处理诸如定时器休眠之类的事件。

    【讨论】:

    • 感谢兄弟的关注,但这不是答案。请用评论替换它!
    • @MoonLight 呃,这显然是一个答案。此外,他告诉你的错误是非常正确的。
    • 对不起@MoonLight,下次我会尽量不告诉你为什么你的代码不起作用。我会为你做所有的工作。
    • @BrianRasmussen 根据上下文,这些似乎是 WinForms/WPF 计时器,而不是线程计时器。所以是的,如果从 UI 线程调用睡眠,则在睡眠完成之前不会执行计时器,因为 UI 没有处理消息。
    【解决方案2】:

    你的计时器就是你的循环,你不需要一个 for 循环。您只需在函数调用之外跟踪循环变量。我建议将所有这些功能包装到一个类中,以使其与您的 GUI 代码分开。

    private int loopVar = 0;
    public void Form_Load()
    {
        // Start 100ms after form load.
        timer1.Interval = 100;
        timer1.Enabled = true;
    }
    
    
    private void timer1_Tick(object sender, EventArgs e)
    {
       timer1.Enabled = false;
       //  My Code Here
       loopVar++;
    
       if (loopVar < Max_Step)
       {
          // Come back to the _tick after 60 seconds.
          timer1.Interval = 60000;
          timer1.Enabled = true;
    
       }
    }
    

    【讨论】:

      【解决方案3】:

      这段代码让我觉得很无聊

      方法:

      private void timer1_Tick(object sender, EventArgs e) {
          timer2.Enabled=false;
          timer1.Enabled=false;
          lblTimer_Value_InBuildings.Text="0";
      }
      
      private void timer2_Tick(object sender, EventArgs e) {
          lblTimer_Value_InBuildings.Text=(int.Parse(lblTimer_Value_InBuildings.Text)+1).ToString();
      }
      
      private void timer3_Tick(object sender, EventArgs e) {
          if(0!=(int)timer3.Tag) {
              // your code goes here and peformed per step
              timer1.Enabled=true;
              timer2.Enabled=true;
          }
      
          timer3.Tag=(1+(int)timer3.Tag)%Max_Step;
      }
      

      姓名首字母:

      var delayedInterval=60000;
      
      timer1.Interval=60000;
      timer2.Interval=1000;
      timer3.Interval=delayedInterval+timer1.Interval;
      
      lblTimer_Value_InBuildings.Text="0";
      timer3.Tag=1;
      timer3.Enabled=true;
      

      您的原始代码永远不会使timer1timer2 停止,所以我认为您应该将timer7timer8 更正为timer1timer2,否则它们在这里没有意义。

      【讨论】:

      • 我不明白,timer3 有什么好处 - 意思是你的代码中的延迟在哪里?
      • 您的代码显示它是一个winform应用程序,即您的UI线程有一个SynchronizationContext。计时器的工作原理解释起来有点复杂,但Sleep 一个线程只是阻塞了其他希望获得与其同步的对象的线程。
      猜你喜欢
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 2021-05-30
      相关资源
      最近更新 更多