为什么Thread.Sleep()以这种方式运行

时间:2012-07-20 10:17:47

标签: c# multithreading

  

可能重复:
  Why does Thread.sleep() behave in this way

这是我写的一个简单的代码:

    private void button1_Click(object sender, EventArgs e)
    {
        label1.Text = "first";
        Thread.Sleep(1000);
        label1.Text = "second";
    }

执行此代码并单击按钮时,label1仅将文本显示为“第二个”而不是“第一个”。我使用断点检查,并执行语句label1.text =“first”但标签不显示“first”。为什么会这样?

4 个答案:

答案 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";
}