【问题标题】:C# While loop thread.sleep in GUIGUI中的C#While循环thread.sleep
【发布时间】:2014-06-25 09:23:51
【问题描述】:

我在调用的委托方法中有一个 while 循环。我的问题是,当它在 while 循环内时,整个 GUI 被冻结,直到它退出 while 循环。我怎样才能使它不会冻结GUI?谢谢

if (!IsUploadingAvailable())
{
    MessageBox.Show("Uploading is not available, please wait until it is ready!", "Upload not available");
    myButton.Enabled = false;

    while (IsUploadingAvailable())
    {
        Thread.Sleep(RandomAmountOfTime(10000)); 
    }
    MessageBox.Show("Uploading is now available!");
}

【问题讨论】:

  • 如果禁用按钮,为什么要执行 Thread.Sleep?
  • 这已经被问过了。我确信已经有关于同一主题的问题得到解答。查看 Winforms 关于“不响应”、“BackgroundWorker”等的问题。

标签: c# multithreading winforms ui-thread


【解决方案1】:

您正在阻塞 GUI 线程。您需要在不同的线程上完成工作,例如通过使用BackgroundWorker 类。

【讨论】:

    【解决方案2】:

    你应该使用Timer

    试试这个:

    System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
    timer1.Interval=10000;//10 seconds
    timer1.Tick += new System.EventHandler(timer1_Tick);
    
    if (!IsUploadingAvailable())
    {
        MessageBox.Show("Uploading is not available, please wait until it is ready!", "Upload not available");
        myButton.Enabled = false;
        while (IsUploadingAvailable())
        {
             timer1.Start();
        }
        MessageBox.Show("Uploading is now available!");
    }
    
    private void timer1_Tick(object sender, EventArgs e)
    {
         //do whatever you want 
          timer1.Stop();
    }
    

    【讨论】:

      【解决方案3】:

      在这里回答:- Thread sleep in a for loop

      您正在阻塞 UI 线程 - 通常不会显示更新,直到 你离开事件处理程序。一种hacky方法是使用 Application.DoEvents(),但这是惰性的并且有重新进入的风险 尤其是在您暂停时。

      更好的方法是在后台线程上完成工作,并使用 调用以将数据推送到 UI(不要从 工作线程)。

      【讨论】:

        【解决方案4】:

        将“快速而肮脏”的应用程序与设计良好的应用程序区分开来的最重要的事情之一是应用程序的用户界面在长时间操作期间的行为方式。快速而简单的方法是在按钮的 Click 事件处理程序中完成所有工作,而不用担心用户界面。这样做的问题是,当应用程序执行它需要做的任何工作时,GUI 将冻结。

        另一方面,一个设计良好的应用程序会小心地在后台线程中做尽可能多的工作,保持 GUI 响应并确保它让用户清楚地知道工作正在进行背景并调整 GUI 以禁止任何在工作完成后才应用的用户操作。

        BackgroundWorker 正是为这种情况而设计的。

        MSDN或使用Task Parallel Library

        【讨论】:

          【解决方案5】:

          使用Task:

          if (!IsUploadingAvailable())
          {
              MessageBox.Show("Uploading is not available, please wait until it is ready!", "Upload not available");
              myButton.Enabled = false;
          
              await WaitForUploadingAvailable();
          
              MessageBox.Show("Uploading is now available!");
          }
          
          async Task WaitForUploadingAvailable()
          {
              await Task.Run(() =>
              {
                  while (!IsUploadingAvailable())
                  {
                      Thread.Sleep(RandomAmountOfTime(10000));
                  }
              });
          }
          

          将包含您的代码的方法声明为async

          【讨论】:

            猜你喜欢
            • 2020-10-24
            • 2012-02-06
            • 1970-01-01
            • 1970-01-01
            • 2012-11-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-11
            相关资源
            最近更新 更多