我想使用VB.NET
创建一个带有此接口的简单计时器
我想按下Button1并开始计算文本框中的秒数。
I do not want to use the Timer Component because it does not offer high resolution.
因此,我决定使用stopWatch Class,因为它的分辨率很高。
但根据我的VB.NET代码,在我看来,整个“dotnet冒险”是不可能的。那是因为当我按下Button1时整个表格冻结了,我不能按下Button2来停止计时器。
我的代码有什么问题吗? 我该怎么做才能拥有上述功能?
提前致谢!
Public Class Form1
Private enableTime As TimeSpan
Private stopWatch As New Stopwatch()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
stopWatch.Start()
If stopWatch.IsHighResolution Then
Do
If stopWatch.ElapsedTicks.Equals(TimeSpan.TicksPerSecond) Then
enableTime = enableTime + TimeSpan.FromSeconds(1)
TextBox1.Text = enableTime.ToString
stopWatch.Restart()
End If
If Not stopWatch.IsRunning Then
Exit Do
End If
Loop
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
stopWatch.Stop()
stopWatch.Reset()
End Sub
结束班
答案 0 :(得分:4)
在WinForms中,有一个UI线程正在执行消息循环。基本上,每个事件都被添加到消息队列中,该消息队列被处理,一个接一个的事件。单击Button1
时,将执行Button1_Click
方法,并且在完成之前不会处理任何其他事件。由于您的设计需要处理Button2.Click
才能终止Button1.Click
中的循环,因此它永远不会终止。
要正确实现您想要的内容,您必须在Button1.Click
上启动秒表,并将UI更新逻辑放入您放置在表单上的计时器的Tick
事件中。
答案 1 :(得分:4)
您正在“失去”时间,因为您手动添加到时间跨度:enableTime = enableTime + TimeSpan.FromSeconds(1)
。使用Stopwatch.Elapsed
属性时,秒表()本身始终准确无误。您需要做的就是从Timer.Tick
事件更新GUI。基本上,计时器只是向秒表询问当前时间是什么,并显示它......无需计算。
以下将每秒更新十次,不会“漂移”,并且不会挂起CPU:
Public Class Form1
Private SW As New Stopwatch
Private WithEvents Tmr As New System.Windows.Forms.Timer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Tmr.Interval = 100
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
SW.Start()
Tmr.Start()
End Sub
Private Sub Tmr_Tick(sender As Object, e As System.EventArgs) Handles Tmr.Tick
TextBox1.Text = SW.Elapsed.ToString
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
SW.Stop()
Tmr.Stop()
SW.Reset()
End Sub
End Class
答案 2 :(得分:1)
一项实验,显示计时器不应用于计时。最好使用计时器定期显示秒表经过的时间。
Public Class Form1
Private stpw As New Stopwatch
Private WithEvents aTimer As New System.Windows.Forms.Timer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
aTimer.Interval = 100 'ten times per second
aTimer.Start() 'start the timer
End Sub
Private Sub timeTick(sender As Object, e As System.EventArgs) Handles aTimer.Tick
If stpw.IsRunning Then
'show that using the timer tick is not accurate for timing
'add the number of ms. to the timespan
'if the tick occurs exactly on the interval this will be accurate
elapsedTM = elapsedTM.Add(New TimeSpan(0, 0, 0, 0, aTimer.Interval))
'show the two elapsed times
'as of .Net 4.0 format elapsed
TextBox1.Text = stpw.Elapsed.ToString("hh\:mm\:ss\.f")
TextBox2.Text = elapsedTM.ToString("hh\:mm\:ss\.f")
'show the time according to the system
TextBox3.Text = DateTime.Now.ToString("hh:mm:ss.f")
'show the time by adding the start time and the stopwatch elapsed time
TextBox4.Text = strt.AddMilliseconds(stpw.ElapsedMilliseconds).ToString("hh:mm:ss.f")
End If
End Sub
Dim strt As DateTime
Dim elapsedTM As TimeSpan
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'start
If Not stpw.IsRunning Then
elapsedTM = New TimeSpan(0L)
'record the start time
strt = DateTime.Now
stpw.Start() 'start the stopwatch
Button2.Select()
End If
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
'stop
stpw.Stop()
stpw.Reset()
Button1.Select()
End Sub
End Class