我如何实现时间延迟?

How do i implement a time delay?

我现在已经进行了 3 周的编程,所以我尝试构建一个记忆游戏。 除了延迟,一切正常。我尝试了很多不同的选择,但不知何故延迟是在 Button_Click 事件结束时。

如果我点击第一个按钮,它会改变内容,但是当我点击第二个按钮时 按钮,无论触发哪个 if 语句,第二张卡片都不会显示。代码在事件结束之前工作正常,然后发生 3 秒的延迟

我想实现的是你可以在短时间内看到第二张卡片 在两张牌都翻过来或消失之前。

P.S。 - 如果我在 "delay" 之后添加 MessageBox 似乎可以工作 但这不是目标,所以是否有类似等待同步或我错过的东西?

代码:

private void Button_Click(object sender, RoutedEventArgs e)
        {
            var button = (Button)sender;
            int index = ContainderGrid.Children.IndexOf(button);

            mCounterSecondPic++;

            button.Content = new BitmapImage(new Uri(mImgPath[mPairs[index]]));//change content
            mPic[mCounterSecondPic-1] = mPairs[index];
            button.IsEnabled = false;

            if (mPic[0] == mPic[1] & mCounterSecondPic == 2)
            {

                mCounterSecondPic = 0;

                new System.Threading.ManualResetEvent(false).WaitOne(3000); //wait for 3sec

                ContainderGrid.Children.RemoveAt(mPairs.IndexOf(mPic[0]));
                 mPairs.RemoveAt(mPairs.IndexOf(mPic[0]));
                 ContainderGrid.Children.RemoveAt(mPairs.IndexOf(mPic[0]));
                 mPairs.RemoveAt(mPairs.IndexOf(mPic[0]));

            }

            if (mCounterSecondPic == 2 & mPic[0] != mPic[1])
            {

                mCounterSecondPic = 0;

                new System.Threading.ManualResetEvent(false).WaitOne(3000);//wait for3 sec

                ContainderGrid.Children.Cast<Button>().ToList().ForEach(resetbuttons =>
                {
                    resetbuttons.IsEnabled = true;
                    resetbuttons.Content = new BitmapImage(new Uri(mCardBack));

                });


            }

ps:如果我在 "delay" 之前添加一个消息框,它似乎可以工作 但这不是问题,所以有没有类似等待同步或我错过的东西?

                MessageBox.Show("x");
                new System.Threading.ManualResetEvent(false).WaitOne(3000);

让我们简化代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    button.Content = "START" //change content
    new System.Threading.ManualResetEvent(false).WaitOne(3000); //wait for 3sec
    button.Content = "FINISH" //change content
}

这样你就有了以下时间表:

  1. 设置内容(但不要see/feel它)
  2. 您开始等待 3 秒
  3. 你结束等待 3 秒
  4. 设置内容(但不要see/feel它)
  5. 您退出 Button_Click 方法
  6. 你居然see/feel内容变了

如您所见,内容更改(在 item1 和 item4)并没有立即发生,而是在很久以后;这是因为 UI 线程在 Button_Click 方法的执行中被阻塞,因此无法刷新图形。
为了实现你想要的,你有两个选择:

  • 使用async/await:
private async void Button_Click(object sender, RoutedEventArgs e)
{
    button.Content = "START" //change content
    await Task.Delay(3000); //wait for 3sec asynchronously
    button.Content = "FINISH" //change content
}
  • 使用Dispatcher:
private void Button_Click(object sender, RoutedEventArgs e)
{
    new Thread(() =>
    {
        Dispatcher.Invoke(() => button.Content = "START");
        System.Threading.Thread.Sleep(3000);
        Dispatcher.Invoke(() => button.Content = "FINISH");
    }).Start();
}