请参阅本文底部的代码。它应该在列表框中添加“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();
}
异步/等待救援:
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();
}
第一:为什么没有发生任何事情?
原因是,您目前处于UI线程中。通过执行Thread.Sleep
,您可以暂停您希望绘制刚刚添加的项目的相同线程。
第二:如何解决这个问题?
正如@CodeCaster所提到的,你可以使用Timer
来做这一切。您也可以将代码放在Thread
中,并使用Add
或Dispatcher
类调用SynchronizationContext
方法,并使用Send
方法。
第三:对Sleep
方法的一点点暗示。
通常它应该做你期望的,但不能保证。调用Sleep
意味着您的线程将被暂停大约您想要的时间。 See this answer
您可以使用间隔设置为Timer
的1000
。当你想要它引发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();
}
在每次listBox1.Refresh();
电话后放一个Sleep()
。
您让线程休眠,但UI不会自动重新绘制。