使用Thread.Sleep时UI不更新

本文关键字:更新 UI Thread Sleep 使用 | 更新日期: 2023-09-27 18:18:08

我有一个应用程序,有按钮,我想当点击这个按钮每1秒添加特殊文本添加到一个文本框,但当点击这个按钮所有时间等待并输入所有文本在一起

是什么问题?

例如:

 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);
            }
        }

谢谢。

使用Thread.Sleep时UI不更新

你正在UI线程上睡觉。
这将冻结UI。

请使用BackgroundWorker及其进度事件。

文本实际上是添加到你的文本框在1秒的间隔,你只是看不到它,直到循环结束,因为你已经把GUI的线程休眠,它无法更新自己

@Slaks是正确的;你正在休眠UI线程。

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

使线程处于睡眠状态会使主线程处于睡眠状态。

以下内容可以使用

创建一个函数

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

这将在每毫秒之后执行事件

你可以用

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);
            }
        }

实现此目的的最佳方法是将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 BackgroundWorker事件中像这样

    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();
    }