4

我想使用 VB.NET 用这个接口创建一个简单的计时器

在此处输入图像描述

我想按 Button1 并开始在文本框中计算秒数。

我不想使用计时器组件,因为它不提供高分辨率。

因此,我决定使用 stopWatch 类,因为它根据规范具有高分辨率。

但根据我下面的 VB.NET 代码,在我看来,整个“dotnet 冒险”是不可能的。那是因为当我按下 Button1 时,它会冻结整个表单,我无法按下 Button2 来停止计时器。

我的代码有什么问题吗?我应该怎么做才能拥有上述功能?

提前致谢!

 
公开课形式1

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

结束类

4

3 回答 3

5

在 WinForms 中,有一个 UI 线程执行消息循环。基本上,每个事件都被添加到消息队列中,一个事件接一个地被处理。当Button1被点击时,该Button1_Click方法被执行并且在它完成之前不会处理其他事件。由于您的设计需要Button2.Click进行处理才能终止循环Button1.Click,它永远不会终止。

要正确实现您想要的,您必须启动秒表Button1.Click并将 UI 更新逻辑放入Tick您放置在表单上的计时器事件中。

于 2013-05-11T11:03:59.520 回答
5

您正在“浪费”时间,因为您手动添加到时间跨度:enableTime = enableTime + TimeSpan.FromSeconds(1). 当您使用 Stopwatch()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
于 2013-05-11T12:46:04.840 回答
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
于 2013-05-11T14:05:02.540 回答