如何有程序等待X秒并允许UI执行



我正在制作带有自动播放功能的小型游戏,但是程序运行得太快,因此用户在每个阶段都看不到结果。我正在使用VS 2017,所以我不能使用异步(至少是从我阅读的内容中)。我该如何等待程序并允许UI更新?

我在循环时在DO中工作。游戏的主要部分执行,更新UI,然后等待播放器单击按钮(假设自动播放未运行),并且在循环重复时自动播放运行DO,但是在UI更新后,它将等待x秒。

使用 Timer组件而不是循环,然后将循环主体放入计时器的Elapsed事件中。

和VS2017 绝对支持async,但是在这种情况下,这对用户来说仍然不会移动太快。

您可以使用异步/等待降低事件处理程序的执行,而无需拆分逻辑。这很简单:

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

您可以在MSDN上阅读有关async/await的信息。

如果您使用的是WPF,则必须查看动画。与手动更改某些东西(位置,尺寸)相比,它们更简单地用于确保更改。

用法:delayfactory.delayaction(500,new Action(()=> {this.runaction();}));

//Note Forms.Timer和Timer()具有相似的实现。//假设您将有一个delayFactory静态类

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

使用计时器,没有UI锁。

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

用法:

wait(1000); //wait one second

看起来您有几个选项

1.您可以尝试睡眠 - (但可能会悬挂UI)

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

2.您可以尝试此代码:

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.尝试使用async,看看发生了什么

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

最新更新