此代码模仿了我在应用程序中遇到的问题。
private void button1_Click(object sender, EventArgs e)
{
button1.BackColor = Color.Red;
Thread.Sleep(3000);
button1.BackColor = Color.Green;
}
我希望这段代码能够实现;
,而是等待3秒钟,然后将按钮变为绿色。我不能只是从一开始就将按钮设为绿色,因为这在我的大型应用程序中将无法使用。
有人知道什么是错的,还有我该如何解决?预先感谢。
答案 0 :(得分:3)
不。它更改为红色,但您阻止了UI线程,因此看不到颜色更改。如果您将处理程序更改为async
这样的
private async Task button1_Click(object sender, EventArgs e)
{
button1.BackColor = Color.Red;
await Task.Delay(3000);
button1.BackColor = Color.Green;
}
答案 1 :(得分:2)
问题是使用Sleep会阻塞主(渲染)线程。因此,您将按钮设置为红色,但由于阻塞了线程,因此应用程序无法呈现该线程。实际上,我希望整个应用程序都冻结。
我不确定您在使用什么,但是请尝试看看一些计时器。
编辑或仅使用任务Delayed function calls。请不要使用线程。
答案 2 :(得分:0)
这样做的技术原因是,UI在消息泵上工作(对于WinForms或类似的WPF)。基本上,消息泵是要执行的工作项目的队列,以及如下所示的while循环
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
正在发生的事情是,在您处理点击时
为什么?
将挂起当前线程指定的时间。
简而言之,没有其他消息得到处理。在您的示例中,您在泵还没有时间来处理您的颜色更改之前就休眠了该线程(它仍然会处理您的单击)。
当邮件最终得到处理时,它会处理待办事项(您的颜色更改是其中的一部分),然后在不暂停的情况下迅速将其从一个更改为另一个。
修复非常简单,您需要让泵在等待时处理消息,而正如其他答案所难免的那样,在.net上的现代版本中,我们可以使用async
await
模式,并利用Task.Delay()
方法。
程序处理带有await
前缀的任何内容时,
嘿。一切都应该如此