Thread.Sleep() 临时暂停程序的替代方案

Alternative for Thread.Sleep() to temporarily suspend program

查看此 post 底部的代码。它应该将“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();
        }

在每个 Sleep() 调用之后添加一个 listBox1.Refresh();

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

首先:为什么什么都没有发生?

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

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

正如@CodeCaster 提到的,您可以使用 Timer 来完成所有这些。您还可以将代码放在 Thread 中,然后使用 DispatcherSynchronizationContext class 调用 Add 方法,它是 Send 方法.

第三:关于Sleep方法的一个小提示。

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

您可以使用将间隔设置为 1000Timer。当您希望它引发 Tick 事件时启动计时器。停止它以停止引发 Tick 事件。间隔处理 Tick 事件和 运行 代码。

但是按照另一个答案中的建议,使用 async-await 实现倒计时 3-2-1 功能是个好主意:

private async void countdown()
{
    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();
}

异步/等待救援:

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();
}