DutchLearner
DutchLearner

Reputation: 335

Alternative for Thread.Sleep() to temporarily suspend program

See the code at the bottom of this post. It's supposed to add "3" to the listbox, then "2" a second later, then "1" a second later and then run the main code of the program. However, once I execute the program it just stays blank 3 seconds long, after which all 3, 2, and 1 are shown, after which all the code directly starts. I want to visually see every number show up with a one second delay. How do I do this?

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

Upvotes: 1

Views: 1865

Answers (4)

Reza Aghaei
Reza Aghaei

Reputation: 125302

You can use a Timer having the interval set to 1000. Start the timer when you want it to raise Tick event. Stop it to stop raising Tick event. Handle the Tick event and run the code in intervals.

But to have a countdown 3-2-1 function using async-await as it's suggested in the other answer is good idea:

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

Upvotes: 1

Oliver
Oliver

Reputation: 45119

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

Upvotes: 8

Steffen Winkler
Steffen Winkler

Reputation: 2864

First: Why isn't anything happening?

The reason is, that you are currently in the UI thread. By doing Thread.Sleep you suspend the very same thread you expect to draw the items you just added.

Second: How to work around this?

As @CodeCaster mentioned, you could use a Timer to do all this. You could also put your code in a Thread and call the Add method by using a Dispatcher or the SynchronizationContext class and it's Send method.

Third: A small hint on the Sleep method.

Usually it should do what you expect it to, but there is no guarantee for that. Calling Sleep means that your thread will be suspended for roughly the amount of time you want it to. See this answer

Upvotes: 5

Roy Dictus
Roy Dictus

Reputation: 33149

Put a listBox1.Refresh(); after every Sleep() call.

You are letting the thread sleep, but the UI does not get repainted automagically.

Upvotes: 0

Related Questions