Borko Djurovic
Borko Djurovic

Reputation: 11

How to delay execution of a part of code in task in C#

I have this method that i need to pause for some period of time. This is what I tried:

private async void btnStart_Click(object sender, RoutedEventArgs e)
    {
        await Task.Run(() =>
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                NewGame();

                // Game Loop
                for (int i = 0; i < 35; i++)
                {
                    int index = _random.Next(0, _numbersInGame.Count);
                    int number = _numbersInGame.ToArray()[index];
                    lblCurrentNumber.Content = number.ToString();

                    Task.Delay(1000).Wait(); // I want to add pause here

                    (this.FindName($"lblNum{i + 1}") as Label).Content = number.ToString();
                    lblCurrentNumber.Content = "";
                    _numbersInGame.RemoveAt(index);
                }
            }));
        });
    }

Any help is welcome. Thanks!

Upvotes: 0

Views: 95

Answers (1)

TheGeneral
TheGeneral

Reputation: 81483

  1. You don't need to offload this to a task (with Task.Run)
  2. Since you aren't offloading, you don't need to marshal back to the UI thread with Invoke.
  3. Given the above, you can idiomatically await a Task.Delay without blocking the UI

Example

private async void btnStart_Click(object sender, RoutedEventArgs e)
{
   for (int i = 0; i < 35; i++)
   {
      NewGame();

      int index = _random.Next(0, _numbersInGame.Count);
      int number = _numbersInGame.ToArray()[index];
      lblCurrentNumber.Content = number.ToString();

      await Task.Delay(100);

      (this.FindName($"lblNum{i + 1}") as Label).Content = number.ToString();
      lblCurrentNumber.Content = "";
      _numbersInGame.RemoveAt(index);
   }
}

Using the async and await pattern like this allows you to safely update the UI as the continuation will be posted back to the UI context. It also allows the Message Pump / Dispatcher to continue unabated until the awaited delay has completed.

Lastly, you might want to protect this method from double clicks with a flag or similar (since the ui is free to reenter)

Upvotes: 2

Related Questions