Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确暂停/延迟Windows窗体应用程序_C#_Winforms_Delay_Thread Sleep_Pause - Fatal编程技术网

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

C# 如何正确暂停/延迟Windows窗体应用程序,c#,winforms,delay,thread-sleep,pause,C#,Winforms,Delay,Thread Sleep,Pause,我是OOP和C的初学者 我正在使用Windows窗体制作一个问答游戏。 我的问题与两个类有关,形式和游戏逻辑。 我有一个带有经典From控件的基本UI。看一看 我想实现的是,当玩家按下任何一个回答按钮时,它会以红色或绿色点亮该按钮,这取决于答案是对还是错。更改颜色后,我希望程序等待一段时间,然后转到下一个问题 问题是,我不知道如何正确实现这一点。我不知道如何使用线程,也不知道表单应用程序如何与线程相关。我应该使用线程睡眠、计时器还是异步 我将向您展示游戏逻辑类中应该处理这个问题的方法 publ

我是OOP和C的初学者

我正在使用Windows窗体制作一个问答游戏。 我的问题与两个类有关,形式游戏逻辑。 我有一个带有经典From控件的基本UI。看一看

我想实现的是,当玩家按下任何一个回答按钮时,它会以红色或绿色点亮该按钮,这取决于答案是对还是错。更改颜色后,我希望程序等待一段时间,然后转到下一个问题

问题是,我不知道如何正确实现这一点。我不知道如何使用线程,也不知道表单应用程序如何与线程相关。我应该使用线程睡眠、计时器还是异步

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

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);
    }
publicstaticvoidplay(char-answer)//方法获取表示palyer答案的char
{
if(_rightAnswer==answer)//如果答案为true,则按钮应变为绿色
{
Program.MainWindow.ChangeBtnColor(答案、系统、绘图、颜色、浅绿色);
_分数++;
}
else//否则按钮变为红色
{
Program.MainWindow.ChangeBtnColor(答案、系统、绘图、颜色、红色);
}
//睡在这里
如果(!(\u currentIndex<\u maxIndex))//如果是最后一个问题,请结束游戏
{
Program.MainWindow.DisplayGameOver(_分数);
}
else//如果不是最后一个问题,则加载下一个问题并显示,最后将按钮颜色更改为默认值
{
_currentIndex++;
_currentQuestion=Database.ListOfQuestions.ElementAt(_currentIndex);
_rightAnswer=\u currentQuestion.rightAnswer;
Program.MainWindow.DisplayStats(_score,_currentIndex+1,_maxIndex+1);
Program.MainWindow.DisplayQuestion(\u currentQuestion.Text);
Program.MainWindow.DisplayChoices(\u currentQuestion.Choices);
}
Program.MainWindow.ChangeBtnColor(应答、系统、绘图、系统颜色、控制灯);
}

我不想完全阻塞UI,但我也不希望用户在暂停期间按其他按钮来进行其他事件。因为这将导致应用程序的不正确运行。

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

一旦用户选择了答案,您可以禁用所有按钮,以便他们不能按任何其他按钮

然后启动计时器,这样就不会阻塞UI。计时器基本上是一个线程,但为您处理所有线程,因此您不必担心这方面的问题


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

在//SLEEP此处添加这行代码

Timer timer = new Timer(new TimerCallback(timerCb), null, 2000, 0);
2000是毫秒,是等待时间,timerCb是回调方法

此外,在该模式下,禁用所有按钮,以便不会生成新事件

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

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

由于
wait
,在GUI场景中挂起执行非常容易:

await Task.Delay(2000);
这不会阻止用户界面

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

不需要定时器或线程。没有回调,没有
调用