使用Thread.Sleep时UI不更新
我有应用程序有我想要的按钮,当每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); } }
谢谢。
你在UI线程上睡觉了。
这会冻结用户界面。
而是使用BackgroundWorker
及其进度事件。
文本实际上是以1秒的间隔添加到文本框中,直到循环结束才会看到它,因为您已将GUI的线程置于hibernate状态并且无法自行更新。
@Slaks是对的; 你在睡觉UI线程。
我建议将计时器作为更优雅的解决方案。 请注意,需要将在另一个线程中引发的事件(例如来自后台工作程序或计时器)编组回到表单的UI线程。
使线程hibernate将使您的主线程hibernate。
以下可能有效
发挥作用
private void wait(int ms) { for(int x=0;x
这将在每个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); } }
实现此目的的最佳方法是将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(); }