繁体   English   中英

C#简单倒计时 - 我做错了什么?

[英]C# Simple Countdown - What am I doing wrong?

我想用C#做一个简单的Countdown-Application作为例子。

对于第一个和最基本的版本,我使用Label来显示剩余的当前时间(以秒为单位)和一个Button来开始倒计时。 Button的Click-Event实现如下:

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())所选的时间量,但Label的上下文未刷新。

我做的事情一般是错的(当谈到线程时)或者它只是UI的一个问题?


谢谢您的回答! 我现在使用System.Windows.Threading.DispatcherTimer来做你告诉我的事情。 一切正常,所以这个问题得到正式回答;)

对于那些感兴趣的人:这是我的代码(基本部分)

public partial class WindowCountdown : Window
{
    private int _time;
    private DispatcherTimer _countdownTimer;

    public WindowCountdown()
    {
        InitializeComponent();
        _countdownTimer = new DispatcherTimer();
        _countdownTimer.Interval = new TimeSpan(0,0,1);
        _countdownTimer.Tick += new EventHandler(CountdownTimerStep);

    }

    private void ButtonStart_Click(object sender, RoutedEventArgs e)
    {
        _time = 10;
        _countdownTimer.Start();

    }

    private void CountdownTimerStep(object sender, EventArgs e)
    {
        if (_time > 0)
        {
            _time--;
            this.labelTime.Content = _time + "s";
        }
        else
            _countdownTimer.Stop();
    }
}

是的,事件处理程序不应该阻止 - 它们应该立即返回。 您应该通过Timer,BackgroundWorker或Thread(按此优先顺序)实现此功能。

您所看到的是阻止Windows消息队列/泵的长时间运行消息的影响 - 您通常将其与白色应用程序屏幕关联并且“无响应”。 基本上,如果你的线程处于休眠状态,它就不会响应像“自己画画”这样的消息。 您需要对泵进行更改并控制

有多种方法可以做到这一点(ripper234可以很好地列出它们)。 你经常看到的方法是:

{ // your count/sleep loop

    // bad code - don't do this:
    Application.DoEvents();
    System.Threading.Thread.Sleep(1000);
}

我提到这一点只是为了强调不该做的事; 这导致了很多“重入”和一般代码管理的问题。 更好的方法是使用Timer或更复杂的代码,使用BackgroundWorker 就像是:

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();
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM