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

问题描述 投票:1回答:4

请参阅本文底部的代码。它应该在列表框中添加“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();
        }
c# wait sleep
4个回答
8
投票

异步/等待救援:

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

5
投票

第一:为什么没有发生任何事情?

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

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

正如@CodeCaster所提到的,你可以使用Timer来做这一切。您也可以将代码放在Thread中,并使用AddDispatcher类调用SynchronizationContext方法,并使用Send方法。

第三:对Sleep方法的一点点暗示。

通常它应该做你期望的,但不能保证。调用Sleep意味着您的线程将被暂停大约您想要的时间。 See this answer


1
投票

您可以使用间隔设置为Timer1000。当你想要它引发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();
}

0
投票

在每次listBox1.Refresh();电话后放一个Sleep()

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

© www.soinside.com 2019 - 2024. All rights reserved.