我有一个WPF应用程序,我想在屏幕上显示某些信息之前睡一会儿。所以这是。 1.单击按钮。
等等
private void RunTest()
{
clearTable();
System.Threading.Thread.Sleep(1000);
this.Cursor = Cursors.Wait;
Label_OS_Result.Content = operatingSystem;
Image_OS.Visibility = Visibility.Visible;
System.Threading.Thread.Sleep(1000);
Label_CPU_Result.Content = procName;
Image_CPU.Visibility = Visibility.Visible;
System.Threading.Thread.Sleep(1000);
}
但是当我点击我的按钮时,它似乎等了几秒钟,然后一次显示所有内容。
这是怎么回事?
答案 0 :(得分:1)
它按预期工作。
Thread.Sleep
停止执行当前线程达指定的时间。因此,当您更改图像的可见性时,它将进一步调用以更改框架中的可见性,然后它将尝试在屏幕上绘制它(无效)。在此操作完成之前休眠线程时,它将没有足够的时间来完成此操作。您只是阻止负责在屏幕上绘制内容的UI线程。
请注意Thread.Sleep
可能不是解决方案,最好是查看DispatcherTimer
或BackgroundWorkers。
答案 1 :(得分:1)
您不希望在显示GUI的线程上Thead.Sleep()
。
相反,您应该尝试await Task.Delay()
。这类似于sleep,但它不会阻止GUI线程。
这将允许所有渲染仍然发生,同时延迟标签的可见性更改。
答案 2 :(得分:1)
它按预期工作。
这可能不是您的预期,但问题在于您的期望。
当您在大多数可视控件上调整属性时会发生什么,最终应该更改控件的外观,首先要对控件属性(即数据)进行内部调整,然后触发重绘。要触发重绘,通常会将消息发布到拥有此可视控件的线程的消息队列中。
此线程通常一次处理一个消息,无论是单击按钮,鼠标移动还是因为您更改了图像而刚刚发布的绘制消息。
但是,该线程基本上是这样编写的(伪代码):
while (true)
{
var message = GetNextMessageFromQueue();
ProcessMessage(message);
}
这个循环最后一次激活时,它开始处理一条消息,最后调用你的代码,现在正在睡觉。
所以基本上,要获取消息泵(实现此循环的代码的典型名称)来继续泵送消息,从而处理您的绘制消息,不要睡觉。
您可能希望将处理分离到不同的线程,或者“在后台”执行某些其他异步处理方式。
请注意,如果您在响应按钮单击或类似操作时开始执行任何类型的冗长处理,而不在后台线程上执行(或者再次使用其他异步方式),则会遇到相同的问题。 GUI似乎已冻结。
然而,这个问题非常普遍,微软最终在Windows中建立了对它的特殊支持。曾经是一个窗口似乎挂起了。但是,现在,如果消息队列“填满”,Windows将淡出窗口并添加一个标题,指示它已停止响应。不是解决方案,但稍好一点。
答案 3 :(得分:0)
睡眠功能表现正确。
最好使用Timer来执行此操作,
// Declare it in the constructor of the class
int level = 0;
Timer timer = new Timer
timer.Interval = 1000;
timer.Tick +=new EventHandler(timer_Tick);
private void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
if (level == 0)
{
Label_OS_Result.Content = operatingSystem;
Image_OS.Visibility = Visibility.Visible;
++level;
}
else if (level == 1)
{
Label_CPU_Result.Content = procName;
Image_CPU.Visibility = Visibility.Visible;
++level;
}
else if (level > 1)
{
this.Cursor = Cursors.Default;
return;
}
timer.Start();
}
private void RunTest()
{
clearTable();
//System.Threading.Thread.Sleep(1000);
timer.Start();
this.Cursor = Cursors.Wait;
}