我的学校项目是制作一个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)
{
}
}
}
原谅我的英文:)
答案 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.Now
,DateTime.UtcNow
等提供了获取当前日期和时间的机制。TimeSpan
用于表示已用时间的持续时间。
Stopwatch
提供了一种测量经过时间的机制。答案 2 :(得分:2)
正如其他人所说,问题的一部分是你在同一个负责更新UI的线程中尝试执行硬循环。不要使用这样的循环,最好使用{ React.createElement('span', { dangerouslySetInnerHTML:{ __html:arr[0] }}, null) }
,因为计时器将在不同的线程中运行,因此您的UI将保持响应。
Timer
具有Timer
属性,用于定义执行任务的频率。在我们的例子中,它将更新文本框文本。我在下面的代码中将此值设置为100毫秒。计时器还有一个Interval
事件,每次Interval过去都会执行。在此事件中,我们将代码更新为文本框文本。
我们应该使用Tick
来衡量已用时间,因为它是为其构建的。 Stopwatch
对象非常适合保留日期,但对于测量时间而言并不准确。
秒表有DateTime
和Start
方法,我们可以通过按钮点击事件调用,所以我们要做的就是先检查秒表是否正在运行。如果是,那么我们停止它。如果不是,那么我们开始吧。
将这些想法放在一起,您的代码可能如下所示:
Stop
答案 3 :(得分:1)