使用Thread.Sleep时UI不更新

时间:2011-12-18 17:34:33

标签: c# wpf

我有应用程序有我想要的按钮,每1秒钟点击此按钮添加特殊文本添加到TextBox但单击此按钮时,等待并一起输入所有文本。

什么是问题?

例如:

 private void button2_Click(object sender, RoutedEventArgs e)
        {
            Random rand = new Random(DateTime.Now.Millisecond);
            textBox1.Text = "";
            for (int i = 0; i < 10; i++)
            {
                textBox1.Text += rand.Next(1,10) + "\n";
                System.Threading.Thread.Sleep(1000);
            }
        }

感谢。

5 个答案:

答案 0 :(得分:6)

你正在UI线程上睡觉 这会冻结用户界面。

相反,请使用BackgroundWorker及其进度事件。

答案 1 :(得分:1)

文本实际上是以1秒的间隔添加到文本框中,直到循环结束才会看到它,因为您已将GUI的线程置于休眠状态并且无法自行更新。

答案 2 :(得分:1)

@Slaks是正确的;你正在睡觉UI线程。

我建议将计时器作为更优雅的解决方案。请注意,需要将在另一个线程中引发的事件(例如来自后台工作程序或计时器)编组回到表单的UI线程。

答案 3 :(得分:0)

使线程休眠将使主线程处于休眠状态。

以下可能会有效

制作一个功能

private void wait(int ms)
{
   for(int x=0;x<ms;x++)
   {
      Thread.Sleep(1);
      System.Windows.Forms.Application.DoEvents();
   }
}

这将在每个MiliSecond之后执行事件

你可以用它

private void button2_Click(object sender, RoutedEventArgs e)
        {
            Random rand = new Random(DateTime.Now.Millisecond);
            textBox1.Text = "";
            for (int i = 0; i < 10; i++)
            {
                textBox1.Text += rand.Next(1,10) + "\n";
                wait(1000);
            }
        }

答案 4 :(得分:0)

实现此目的的最佳方法是将BackgroundWorker与INotifyPropertyChanged结合使用

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

并实现属性

    private string _value;
    public string Value
    {
        get { return _value; }
        set
        {
            if(value.Equals(_value)) return;
            _value = value;
            NotifyPropertyChanged("Value");
        }
    }

调用方法

    private void Foo()
    {
        var rand = new Random(DateTime.Now.Millisecond);

        for (var i = 0; i < 50; i++)
        {
            Value += rand.Next(1, 10) + "\n";
            System.Threading.Thread.Sleep(500);
        }
    }

事件DoWork Ba​​ckgroundWorker就像这样

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerAsync();
    }


    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        Foo();
    }