progowl
progowl

Reputation: 61

How to have program wait X seconds and allow UI to execute?

I am making a small game with an auto play feature, but the program runs too fast so the user can't see the outcome at each stage. I am using VS 2017, so I can't use async (at least from what I have read). How can I have the program wait and allow the UI to update?

I am working in a do while loop. The main chunk of the game executes, updates the UI, and then waits for the player to click a button (assuming auto play is not running), with auto play running the do while loop repeats, but after the UI updates it would wait X seconds.

Upvotes: 0

Views: 1180

Answers (5)

Said
Said

Reputation: 493

Wait function using timers, no UI locks.

public void wait(int milliseconds)
{
    System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
    if (milliseconds == 0 || milliseconds < 0) return;
    //Console.WriteLine("start wait timer");
    timer1.Interval = milliseconds;
    timer1.Enabled = true;
    timer1.Start();
    timer1.Tick += (s, e) =>
    {
        timer1.Enabled = false;
        timer1.Stop();
        //Console.WriteLine("stop wait timer");
    };
    while (timer1.Enabled)
    {
        Application.DoEvents();
    }
}

Usage:

wait(1000); //wait one second

Upvotes: 0

Mark Rowe
Mark Rowe

Reputation: 979

Usage: DelayFactory.DelayAction(500, new Action(() => { this.RunAction(); }));`

//Note Forms.Timer and Timer() have similar implementations. //Assumes you will have a DelayFactory Static Class

public static void DelayAction(int millisecond, Action action)
{
    var timer = new DispatcherTimer();
    timer.Tick += delegate

    {
        action.Invoke();
        timer.Stop();
    };

    timer.Interval = TimeSpan.FromMilliseconds(millisecond);
    timer.Start();
}

Upvotes: 0

Ess Kay
Ess Kay

Reputation: 598

It looks like you have a couple of options

1.You can try Sleep -(but it may hang the UI)

 int Seconds = 1;
 Threading.Thread.Sleep(Seconds * 1000);

2.You can try this code:

int Seconds = 1;
Private void WaitNSeconds(int seconds)
    { 
       if (seconds < 1) return;
         DateTime _desired = DateTime.Now.AddSeconds(seconds);
         while (DateTime.Now < _desired) {
              System.Windows.Forms.Application.DoEvents();
         }
     }

3.Try to use Async and see what happens

async Task MakeDelay() {
      await Task.Delay(5000); 
}   
private async void btnTaskDelay_Click(object sender, EventArgs e) {
      await MakeDelay();          
}

Upvotes: -1

Sinatr
Sinatr

Reputation: 21969

You can use async/await to slow down the execution of event handler without having to split the logic. This is pretty simple:

async void Button_Click(object sender, RoutedEventArgs e) // wpf event handler
{
    ...
    await Task.Delay(1000); // pause 1 second
    ...

    while (someCondition)
    {
        ...
        await Task.Delay(1000);
        ...
    }
}

You can read about async/await at msdn.

If you are using WPF, then you have to look into animations. They are much simpler to use to ensure smooth changes than manually changing something (position, sizes).

Upvotes: 0

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

Use a Timer component instead of a loop, and put the loop body in the timer's Elapsed event.

And VS2017 definitely supports async, but it wouldn't help in this case... things would still move too fast for the user.

Upvotes: 4

Related Questions