我正在用 C# 编写一个问答游戏。如果用户猜对了,GUI窗体的背景颜色必须变为绿色3秒,如果用户猜错了,GUI窗体的背景颜色必须变为红色3秒。 3 秒后,GUI 表单的背景颜色必须变回白色。然而,当程序暂停 3 秒时,表单的背景颜色完全没有变化。
这是我的代码:
private void KontroleerAntwoord()
{
if (keuse == vrae[ranNum].Antwoord)
{
this.BackColor = Color.Green;
foreach (Control c in this.Controls)
if (c is RadioButton)
((RadioButton)c).BackColor = Color.Green;
}
else
{
this.BackColor = Color.Red;
foreach (Control c in this.Controls)
if (c is RadioButton)
{
if (((RadioButton)c).Text == vrae[ranNum].Antwoord)
c.BackColor = Color.Yellow;
else
c.BackColor = Color.Red;
}
}
Thread.Sleep(3000);
}
我应该做什么来修复它?
永远不要在 UI 线程上使用
Thread.Sleep();
。这将“阻止”线程并阻止它执行其他任何操作,例如更新 UI。
简单的解决方法是使用
await Task.Delay(...)
代替。
private async Task KontroleerAntwoord()
{
// Set color to red
await Task.Delay(3000);
// Set color to white
}
这将在内部使用计时器,以便 UI 线程永远不会被阻塞。请注意,如果您在 3 秒延迟内多次运行此方法,这可能会导致奇怪的行为。因此,您可能想要执行一些操作,例如在延迟之前递增成员变量,并在延迟之后递减它,并且仅在变量为零时重置颜色。
问题在于您在 UI 线程上调用
Sleep()
。一种方法是使用计时器,如下所示。
注意,我将原来的
BackColor
存储在成员中,并用它来恢复延迟后的颜色。
Color orgBackColor; // add this data member
void MyActionOnUIThread()
{
// Keep the current color and change it:
orgBackColor = this.BackColor;
this.BackColor = Color.Green;
// Use a timer to restore the color after 3 seconds:
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 3000;
timer.Tick +=
(object obj, EventArgs args) =>
{
this.BackColor = orgBackColor;
timer.Stop();
};
timer.Start();
}