请参阅本文底部的代码。它应该在列表框中添加“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();
}
答案 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
中,并使用Add
或Dispatcher
类及其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不会自动重新绘制。