这是我写的一个简单的代码:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
Thread.Sleep(1000);
label1.Text = "second";
}
执行此代码并单击按钮时,label1仅将文本显示为“第二个”而不是“第一个”。我使用断点检查,并执行语句label1.text =“first”但标签不显示“first”。为什么会这样?
答案 0 :(得分:4)
因为您的代码在UI线程上运行。
当您的应用程序正在运行而您没有点击某些内容时,应用程序的主要线程就会四处奔波,等待事件,处理Windows消息以及绘制屏幕。当您单击按钮时,应用程序将停止执行这些操作,并改为运行您的功能。当它正在运行您的方法时,它无法绘制屏幕。您的函数将标签设置为“First”,将线程阻塞一秒,然后将标签设置为“second”。
当您返回时,控制权将传回给应用程序,然后可以自由重新绘制表单。它使用“第二”标签重新绘制它。消息循环从未有机会用“第一个”标签绘制它。
答案 1 :(得分:3)
您正在运行单线程应用程序。尽管已经执行了将label1对象的Text属性设置为“first”的语句,但由于导致主应用程序线程暂停,因此"Windows Message Pump"未被执行。
答案 2 :(得分:1)
问题是你在这里冻结了UI线程。
文字"第一"设置但是然后你将主GUI线程置于休眠状态 - 因此UI不会被绘制。
睡眠阶段结束后,文字"秒"设置并绘制UI。
这就是Windows的工作方式,所以你必须以不同的方式做到这一点。 例如使用Threads或Backgroundworker
答案 3 :(得分:0)
如果你想延迟使用计时器。
你没有在UI中看到结果的原因是因为Dipatcher的优先事项。 Render任务的优先级低于执行。
这有助于你:定时器!
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1);
dispatcherTimer.Start();
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
//your code goes here
}
如果你在WPF工作,你可以试试这个:
private void button1_Click(object sender, RoutedEventArgs e)
{
label1.Text = "first";
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
Thread.Sleep(1000);
label1.Text = "second";
}