C# 在线程休眠之前代码不执行?
我这样做:C# 在线程休眠之前代码不执行?,c#,.net,multithreading,winforms,C#,.net,Multithreading,Winforms,我这样做: clear(); coinRefundComplete.Visible = true; state = 0; System.Threading.Thread.Sleep(4000); clear(); greeting.Visible = true; rate.Visible = true; refundTicket.Visible = true; currentTime.Visible = true; 我希望complete文本(它是一个标签)出现4秒钟,然后通过我用clea
clear();
coinRefundComplete.Visible = true;
state = 0;
System.Threading.Thread.Sleep(4000);
clear();
greeting.Visible = true;
rate.Visible = true;
refundTicket.Visible = true;
currentTime.Visible = true;
我希望
complete
文本(它是一个标签)出现4秒钟,然后通过我用clear()定义的方法清除,然后发生一些其他事情。相反,在我用第一个clear()清除表单后,我的表单会空白4秒钟,然后正确完成。使用async/await
方法。使您的方法
异步
-下面是按钮单击的eventhandler示例
private async void ButtonClick(object sender, EventArgs e)
{
clear();
coinRefundComplete.Visible = true;
state = 0;
await Task.Delay(4000);
clear();
greeting.Visible = true;
rate.Visible = true;
refundTicket.Visible = true;
currentTime.Visible = true;
}
在线<代码>等待任务。延迟(4000)将发布代码>UI线程,该线程将更新之前所做的所有更改。4秒后,该方法将继续在UI线程上执行。更新[2018年4月22日]:我没有删除此答案,以便您不会走错方向,即使我的答案确实是OP问题的可能解决方案(特别是当它也会让我损失一些负面声誉时)。您应该阅读下面的帖子,真正说服自己为什么
应用程序。DoEvents
不是解决此问题的好方法:
您的UI没有刷新,因为您在UI线程上执行整个处理,所以UI线程没有机会刷新UI元素。您需要在任何地方调用
Application.DoEvents()
函数,以便刷新UI并加载最新的更改。这是你修改过的代码。在当前UI线程上调用sleep之前,我添加了一行代码:
clear();
coinRefundComplete.Visible = true;
state = 0;
//new line of code
System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(4000);
clear();
greeting.Visible = true;
rate.Visible = true;
refundTicket.Visible = true;
currentTime.Visible = true;
尽管将GUI线程置于睡眠状态从来都不是可取的,但允许GUI线程在进入睡眠状态之前刷新控件状态将向您显示所需的更改。在使其可见之后和进入睡眠之前调用或,以便GUI线程能够在进入睡眠之前显示更改
clear();
coinRefundComplete.Visible = true;
label1.Update();
state = 0;
System.Threading.Thread.Sleep(4000);
clear();
您在使用时应该小心,在您的情况下,这是GUI线程,GUI将对您的睡眠时间不负责任。了解您想要阻止线程的原因可以带来其他更好的建议
编辑
您可以使用其他线程来添加延迟,而不阻塞GUI线程。如果您可以使用framework4.5,那么您可以使用construct或阅读本文
您正在阻止UI线程。更改将不可见,您不应该阻止它。如果您想在一段时间内显示某些内容,请使用计时器。如果所有这些代码都在一个方法中,则在完全执行该方法之前,表单不会更新。插入
Application.DoEvents()代码>之前<代码>系统.线程.线程.睡眠(4000)代码>-给UI一个机会重新绘制label@Fabio,那么你是说我不能在一个方法中多次清除表单?@DmitryBychenko-Application.DoEvents()
不好。就像在UI线程上调用Thread.Sleep(…)
一样糟糕,或者可能更糟。谢谢,这就是我要找的。我发现了许多使用这种技术的问题和答案,但没有一个指出我需要在按钮单击的方法定义中添加“async”。虽然我认为这种实现更好,因为它不会冻结UI,我将另一个答案标记为正确,因为它提供了一个与我原来问题相同的解决方案(尽管不如整体解决方案好)。@73est-另一个解决方案是个坏主意。它不能保证工作。你永远不应该只睡UI线程。这个答案要好得多。我理解这一点,并且在我的实现中使用了这个解决方案。但就目前情况而言,另一种解决方案回答了我的问题,即理论上如何在这种场景中使用Thread.Sleep()。调用Application.DoEvents()
,就是不好。非常糟糕。它会导致各种各样的重新进入错误。它只有在与VB6向后兼容的情况下才可用。不惜一切代价避免它。
private async void testAsyncAwaitDely_Click(object sender, EventArgs e)
{
clear();
coinRefundComplete.Visible = true;
state = 0;
await Task.Delay(4000);
clear();
//Your code
}