Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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# 简单倒计时-我做错了什么?_C#_Wpf_Multithreading - Fatal编程技术网

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

C# 简单倒计时-我做错了什么?,c#,wpf,multithreading,C#,Wpf,Multithreading,我想用C#制作一个简单的倒计时应用程序作为示例 对于第一个也是最基本的版本,我使用一个标签以秒为单位显示当前剩余时间,并使用一个按钮开始倒计时。按钮的单击事件的实现方式如下: private void ButtonStart_Click(object sender, RoutedEventArgs e) { _time = 60; while (_time > 0) { _time--;

我想用C#制作一个简单的倒计时应用程序作为示例

对于第一个也是最基本的版本,我使用一个标签以秒为单位显示当前剩余时间,并使用一个按钮开始倒计时。按钮的单击事件的实现方式如下:

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