C# 简单倒计时-我做错了什么?
我想用C#制作一个简单的倒计时应用程序作为示例 对于第一个也是最基本的版本,我使用一个标签以秒为单位显示当前剩余时间,并使用一个按钮开始倒计时。按钮的单击事件的实现方式如下:C# 简单倒计时-我做错了什么?,c#,wpf,multithreading,C#,Wpf,Multithreading,我想用C#制作一个简单的倒计时应用程序作为示例 对于第一个也是最基本的版本,我使用一个标签以秒为单位显示当前剩余时间,并使用一个按钮开始倒计时。按钮的单击事件的实现方式如下: private void ButtonStart_Click(object sender, RoutedEventArgs e) { _time = 60; while (_time > 0) { _time--;
private void ButtonStart_Click(object sender, RoutedEventArgs e)
{
_time = 60;
while (_time > 0)
{
_time--;
this.labelTime.Content = _time + "s";
System.Threading.Thread.Sleep(1000);
}
}
现在,当用户单击按钮时,时间实际上是倒计时的(因为应用程序冻结了(由于Sleep()),但标签的上下文没有刷新
我是在做一些通常是错误的事情(当涉及到线程时)还是仅仅是UI的问题
谢谢你的回答! 我现在使用System.Windows.Threading.Dispatcher来执行您告诉我的操作。一切正常,因此正式回答了这个问题;) 对于那些感兴趣的人:这是我的代码(基本部分)
是的,事件处理程序不应该阻塞-它们应该立即返回。
您应该通过计时器、BackgroundWorker或线程(按此优先顺序)来实现这一点。您看到的是长时间运行的消息阻塞windows消息队列/泵的效果-您通常会将其与白色应用程序屏幕和“无响应”联系起来。基本上,如果你的线程处于睡眠状态,它不会响应像“粉刷你自己”这样的消息。您需要对泵进行更改和产量控制 有多种方法可以做到这一点(ripper234很好地列出了它们)。你经常看到的坏的方式是:
{ // your count/sleep loop
// bad code - don't do this:
Application.DoEvents();
System.Threading.Thread.Sleep(1000);
}
我提到这个只是为了强调不做的事情;这就导致了“重入”和通用代码管理方面的许多问题。更好的方法是简单地使用计时器
,或者对于更复杂的代码,使用后台工作人员
。比如:
using System;
using System.Windows.Forms;
class MyForm : Form {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new MyForm());
}
Timer timer;
MyForm() {
timer = new Timer();
count = 10;
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
protected override void Dispose(bool disposing) {
if (disposing) {
timer.Dispose();
}
base.Dispose(disposing);
}
int count;
void timer_Tick(object sender, EventArgs e) {
Text = "Wait for " + count + " seconds...";
count--;
if (count == 0)
{
timer.Stop();
}
}
}
using System;
using System.Windows.Forms;
class MyForm : Form {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new MyForm());
}
Timer timer;
MyForm() {
timer = new Timer();
count = 10;
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
protected override void Dispose(bool disposing) {
if (disposing) {
timer.Dispose();
}
base.Dispose(disposing);
}
int count;
void timer_Tick(object sender, EventArgs e) {
Text = "Wait for " + count + " seconds...";
count--;
if (count == 0)
{
timer.Stop();
}
}
}