如何正确暂停/延迟Windows窗体应用程序

时间:2015-12-12 14:00:24

标签: c# winforms delay thread-sleep pause

我是OOP和C#的初学者。

我正在使用Windows窗体进行测验游戏。 我的问题与两个类有关,表单游戏逻辑。 我有一个基本的UI与经典的Froms控件。看一看。

UI layout

我想要达到的目标是,当玩家按下任何一个接听按钮时,按下红色或绿色的按钮会高亮显示,这取决于它是对还是错的答案。更改颜色后,我希望程序等待一段时间,然后转到下一个问题。

Probelm是,我不知道如何正确实现这一点。我不知道如何使用线程以及Form应用程序与线程的关系。我应该使用线程睡眠或计时器还是异步?

我将向您展示游戏逻辑类中应该处理此问题的方法。

public static void Play(char answer) //Method gets a char representing a palyer answer
    {
        if (_rightAnswer == answer) //If the answer is true, the button should become green
        {
            Program.MainWindow.ChangeBtnColor(answer, System.Drawing.Color.LightGreen);
            _score++;
        }
        else //Otherwise the button becomes Red
        {
            Program.MainWindow.ChangeBtnColor(answer, System.Drawing.Color.Red);
        }

        //SLEEP HERE

        if (!(_currentIndex < _maxIndex)) //If it is the last question, show game over
        {
            Program.MainWindow.DisplayGameOver(_score);
        }
        else //If it is not the last question, load next question and dispaly it and finally change the button color to default
        {
            _currentIndex++;
            _currentQuestion = Database.ListOfQuestions.ElementAt(_currentIndex);
            _rightAnswer = _currentQuestion.RightAnswer;
            Program.MainWindow.DisplayStats(_score, _currentIndex + 1, _maxIndex + 1);
            Program.MainWindow.DisplayQuestion(_currentQuestion.Text);
            Program.MainWindow.DisplayChoices(_currentQuestion.Choices);
        }
        Program.MainWindow.ChangeBtnColor(answer, System.Drawing.SystemColors.ControlLight);
    }

我不想完全阻止用户界面,但我也不希望用户在暂停期间按其他按钮来制作其他事件。因为它会导致应用程序运行不正常。

4 个答案:

答案 0 :(得分:2)

如果程序非常简单并且您不想实现Threads,我建议使用Timer。单击答案按钮即可启动计时器。你的计时器应该包含一段时间后会自行停止并执行其他操作的功能(例如选择另一个问题)。

答案 1 :(得分:1)

用户选择了答案后,您可以停用所有按钮,这样他们就无法按任何其他内容。

然后启动计时器,这样您就不会阻止UI。计时器 基本上是一个线程,但处理所有线程,所以你不必担心这个方面。

当计时器达到所需的延迟时,停止并启动一个事件以选择下一个问题。

答案 2 :(得分:0)

在// @ SLEEP HERE添加这行代码

Timer timer = new Timer(new TimerCallback(timerCb), null, 2000, 0);

2000是毫秒并且是等待时间,timerCb是回调方法。

此外,禁用所有按钮,以便不会生成新事件。

private void timerCb(object state)
    {
        Dispatcher.Invoke(() =>
        {
            label1.Content = "Foo!";              
        });
    }

您可以在回调中执行任何操作,但是如果您执行的操作会更改UI中的任何内容,则需要使用Dispatcher,就像我更改标签内容一样。

答案 3 :(得分:0)

由于await

,暂停GUI场景中的执行非常容易
await Task.Delay(2000);

这不会阻止用户界面。

您应该研究await做什么以及如何使用它。如果您从未听说过并且正在编写WinForms,那么您做错了。

不需要计时器或线程。没有回调,没有Invoke