使用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);
}
}
谢谢。
你正在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();
}