首页 > 解决方案 > 如何在C#中延迟执行任务中的部分代码

问题描述

我有这种方法,我需要暂停一段时间。这是我尝试过的:

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

欢迎任何帮助。谢谢!

标签: c#wpfmultithreading

解决方案


  1. 您无需将其卸载任务(使用Task.Run
  2. 由于您没有卸载因此不需要使用Invoke.
  3. 鉴于上述情况,您可以惯用地awaita而Task.Delay不会阻塞UI

例子

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

像这样使用 async 和 await 模式可以让您安全地更新 UI,因为延续将被发送回 UI 上下文。它还允许消息泵/调度程序继续有增无减,直到等待的延迟完成。

最后,您可能希望保护此方法免受带有标志或类似内容的双击(因为 ui 可以自由重新输入)


推荐阅读