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
中,然后使用 Dispatcher
或 SynchronizationContext
class 调用 Add
方法,它是 Send
方法.
第三:关于Sleep
方法的一个小提示。
通常它应该按照您的预期进行,但不能保证。调用 Sleep
意味着您的线程将暂停 大致 您希望的时间。 See this answer
您可以使用将间隔设置为 1000
的 Timer
。当您希望它引发 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();
}
查看此 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
中,然后使用 Dispatcher
或 SynchronizationContext
class 调用 Add
方法,它是 Send
方法.
第三:关于Sleep
方法的一个小提示。
通常它应该按照您的预期进行,但不能保证。调用 Sleep
意味着您的线程将暂停 大致 您希望的时间。 See this answer
您可以使用将间隔设置为 1000
的 Timer
。当您希望它引发 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();
}