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
}