替代Thread.Sleep()暂时挂起程序

时间:2015-09-16 12:21:55

标签: c# wait sleep

请参阅本文底部的代码。它应该在列表框中添加“3”,然后在一秒钟后添加“2”,然后在一秒钟后添加“1”,然后运行程序的主代码。但是,一旦我执行程序,它就会保持3秒钟的空白,然后显示所有的3,2和1,之后所有代码都会直接启动。我想在视觉上看到每个数字都显示一秒延迟。我该怎么做?

private void Main()
        {
            countdown();
            //Main Code
        }

private void countdown()
        {
            listBox1.Items.Clear();
            listBox1.Items.Add("3");
            System.Threading.Thread.Sleep(1000);
            listBox1.Items.Add("2");
            System.Threading.Thread.Sleep(1000);
            listBox1.Items.Add("1");
            System.Threading.Thread.Sleep(1000);
            listBox1.Items.Clear();
        }

4 个答案:

答案 0 :(得分:8)

async / await to the rescue:

private async void OnButtonClick(object sender, EventArgs e)
{
    listBox1.Items.Clear();
    listBox1.Items.Add("3");
    await Task.Delay(1000);

    listBox1.Items.Add("2");
    await Task.Delay(1000);

    listBox1.Items.Add("1");
    await Task.Delay(1000);

    listBox1.Items.Clear();
}

答案 1 :(得分:5)

首先:为什么没有发生任何事情?

原因是,您目前处于UI线程中。通过执行Thread.Sleep,您可以暂停您希望绘制刚刚添加的项目的相同线程。

第二:如何解决这个问题?

正如@CodeCaster所提到的,您可以使用Timer来完成所有这些操作。您也可以将代码放在Thread中,并使用AddDispatcher类及其SynchronizationContext方法调用Send方法

第三次Sleep方法的一个小提示。

通常它应该按照您的预期进行,但不能保证。调用Sleep意味着您的线程将暂停大致您想要的时间。 See this answer

答案 2 :(得分:1)

您可以使用间隔设置为position_offset_gap的{​​{1}}。如果希望它引发Timer事件,请启动计时器。停止它以停止提升1000事件。处理Tick事件并按间隔运行代码。

但是要使用async-await进行倒计时3-2-1功能,因为它在另一个答案中的建议是个好主意:

Tick

答案 3 :(得分:0)

每次listBox1.Refresh();来电后加Sleep()

您让线程休眠,但UI不会自动重新绘制。