【问题标题】:Program hangs on For loop when updating label更新标签时程序挂在 For 循环
【发布时间】:2011-02-07 09:15:52
【问题描述】:

我在一个 winform 应用程序中有这段代码:

for (int i = 1; i <= 20; i++)
 {
      lbl.Text = i.ToString();
      Thread.Sleep(100);
 }

我希望看到标签进度从 1 到 20,但它只是在 for 循环运行时挂起,然后显示 20,即我没有看到 1-19。

为什么会这样?有没有办法像模拟时钟上的毫秒一样快速更新标签文本(我不是在做时钟,只是一个例子。)

谢谢

*编辑:如果我有一个带有事件的按钮也会发生这种情况,该事件在没有 Thread.Sleep 的情况下增加数字但我有一个 beginInvoke 来播放 wav 文件 *

【问题讨论】:

    标签: c# .net winforms for-loop freeze


    【解决方案1】:

    您正在休眠 gui 线程,因此在 gui 再次更新其休眠之前。

    尝试使用刻度为 100 毫秒的计时器

    【讨论】:

      【解决方案2】:

      在睡眠前调用Application.DoEvents();,它将处理队列中的所有消息:

      for (int i = 1; i <= 20; i++)
       {
            lbl.Text = i.ToString();
            Application.DoEvents();
            Thread.Sleep(100);
       }
      

      【讨论】:

        【解决方案3】:

        应用程序挂起并且您只看到20 只是因为这似乎是在UI 线程上执行而您正在Sleep 执行它,因此阻塞了窗口消息循环。但是,即使不是这种情况,您也很可能只会看到20,因为循环执行得非常快。

        使用System.Threading.Timerx 毫秒执行一次,并通过在 UI 线程上调用适当的方法来更新您的标签。

        以下帖子演示了如何实现您可能想要的东西(尽管在 WPF 环境中,但原理是相同的 - 将 ISynchronizeInvoke 用于 WinForms,而不是 WPF 中显示的 Dispatcher 此处):

        Timer callback closes WPF app (DispatcherTimer works..)

        【讨论】:

          【解决方案4】:

          使用定时器控件

          int i=0;
               private void timer_Tick(object sender, EventArgs e)
                      {
                          if(i <=20)
                          { 
                              lbl.Text = i.ToString(); 
                          } 
                       i++;
                      }
          

          根据需要设置 TimerInterval(间隔 1000 = 1 秒)

          【讨论】:

            猜你喜欢
            • 2020-11-29
            • 1970-01-01
            • 2017-07-20
            • 2022-08-14
            • 1970-01-01
            • 2016-03-21
            • 2019-06-05
            • 2018-07-31
            • 1970-01-01
            相关资源
            最近更新 更多