DateTime类作为秒表

时间:2018-01-26 22:43:24

标签: c# datetime

我的学校项目是制作一个c#aplication,只需一个按钮开始/停止,开始计算时间,再次点击停止计算时间。 当我用这3行时

txtVrijeme.Text = Convert.ToString(sada.AddSeconds(i).ToString("HH:mm:ss"));
Thread.Sleep(1000);
i++;

没有循环(而对于,goto等)在表单apk中。它工作(显示00:00:00,如果我再次点击00:00:01)但是当我使用循环它不显示任何东西。为什么?顺便说一句。 console aplication与此代码一起使用没有任何问题(在控制台中循环)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BradičićManuelŠtoperica
{
    public partial class Form1 : Form
    {
        DateTime sada = new DateTime(2009, 6, 22, 0, 0, 0);
        int i = 0;
        bool x = true;

        public Form1()
        {
            InitializeComponent();                
        }

        void execute(bool y)
        {

            while (y == true)
             {
                txtVrijeme.Text = Convert.ToString(sada.AddSeconds(i).ToString("HH:mm:ss"));
                Thread.Sleep(1000);
                i++;
            }
        }


        private void btnStartStop_Click(object sender, EventArgs e)
        {      
            if (x == false)
                  x = true;    
            else
                  x = false;

            execute(x);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {    
        }    
    }
}

Class HashSet

原谅我的英文:)

4 个答案:

答案 0 :(得分:5)

更改文本框属性不会直接在屏幕上绘制任何内容。

再说一遍:

更改文本框属性不会直接在屏幕上绘制任何内容。

Textbox控件会使其图形区域无效,这将导致生成WM_PAINT消息。

程序需要在更新屏幕之前处理此WM_PAINT消息。接收和处理绘制事件的线程是运行execute()方法的相同线程。它也是处理btnStartStop_Click()方法的相同主题

不幸的是,execute()方法永远不会完成。它永远不会允许该线程上的执行回退到您的程序的主消息循环,因此您的程序无法重新绘制文本框,它无法处理最终可能执行execute()的按钮单击方法停止。即使它暂停,它也会让整个线程都处于睡眠状态。

您需要做的是使用Timer组件,并处理Timer的Tick事件。

此外,计时器事件并不完全准确。每个Tick事件的轻微差异可能会随着时间的推移而增加,因此,不是为每个事件增加当前值,而是应该记住开始时间并计算与当前时间的差异。

答案 1 :(得分:2)

不要使用DateTime。而是创建Stopwatch(在System.Diagnostics命名空间中)。您不需要自己增加它 - 只需在单击按钮时启动它,然后评估其Elapsed属性以获取经过的持续时间(这是TimeSpan类型)。

是的,您还需要定时器来定期更新显示。该计时器可以随心所欲地发射,并且可能不精确 - 因为它不负责更新秒表,只是为了将秒表的当前值写入显示器。

总结:

  • DateTime用于表示日期和时间。
    • DateTime.NowDateTime.UtcNow等提供了获取当前日期和时间的机制。
  • TimeSpan用于表示已用时间的持续时间。
    • Stopwatch提供了一种测量经过时间的机制。
  • 将显示更新与时间测量分开。它们是不同的问题。

答案 2 :(得分:2)

正如其他人所说,问题的一部分是你在同一个负责更新UI的线程中尝试执行硬循环。不要使用这样的循环,最好使用{ React.createElement('span', { dangerouslySetInnerHTML:{ __html:arr[0] }}, null) } ,因为计时器将在不同的线程中运行,因此您的UI将保持响应。

Timer具有Timer属性,用于定义执行任务的频率。在我们的例子中,它将更新文本框文本。我在下面的代码中将此值设置为100毫秒。计时器还有一个Interval事件,每次Interval过去都会执行。在此事件中,我们将代码更新为文本框文本。

我们应该使用Tick来衡量已用时间,因为它是为其构建的。 Stopwatch对象非常适合保留日期,但对于测量时间而言并不准确。

秒表有DateTimeStart方法,我们可以通过按钮点击事件调用,所以我们要做的就是先检查秒表是否正在运行。如果是,那么我们停止它。如果不是,那么我们开始吧。

将这些想法放在一起,您的代码可能如下所示:

Stop

答案 3 :(得分:1)

您的项目无效,因为您永远不会离开while。 你应该尝试使用Timer。

了解它here

我认为this video必须帮助你。