使用 VB.NET 的秒表循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16496309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 13:33:32  来源:igfitidea点击:

StopWatch Loop using VB.NET

vb.nettimestopwatch

提问by Novemberland

I want to create a simple timer with this interface using VB.NET

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

enter image description here

在此处输入图片说明

I want to press Button1 and to start counting seconds in the textbox.

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

I do not want to use the Timer Component because it does not offer high resolution.

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

So, I decided to use a stopWatch Class due to its high resolution according to specifications.

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

But according to my VB.NET code below it seems to me that the whole "dotnet adventure" is impossible. That is because when I press Button1 the whole form it freezes and I cannot press Button2 to stop the timer.

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

Is there anything wrong with my code? What should I do to have the functionality described above?

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

Thanks in advance!

提前致谢!

 
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

End Class

结束班

回答by Andreas

In WinForms, there is one UI thread executing the message loop. Basically, every event is added to the message queue, which is processed, one event after another. When Button1is clicked, the Button1_Clickmethod is executed and no other event will be processed until it finishes. Since your design requires Button2.Clickto be processed in order to terminate the loop in Button1.Click, it will never terminate.

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

To correctly implement what you want, you'd have to start the stopwatch on Button1.Clickand put the UI update logic into the Tickevent of a timer which you place on the form.

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

回答by Idle_Mind

You are "losing" time because you're manually adding to a timespan: enableTime = enableTime + TimeSpan.FromSeconds(1). The Stopwatch() itself is always accurate when you use its Stopwatch.Elapsedproperty. All you need to do is update the GUI from a Timer.Tickevent. Basically the Timer just asks the Stopwatch what the current time is and displays it...no calculations needed.

您正在“浪费”时间,因为您正在手动添加时间跨度:enableTime = enableTime + TimeSpan.FromSeconds(1)。当您使用它的Stopwatch.Elapsed属性时, Stopwatch() 本身总是准确的。您需要做的就是从Timer.Tick事件更新 GUI 。基本上计时器只是询问秒表当前时间是什么并显示它......不需要计算。

The following will update ten times a second, will not "drift", and will not peg the CPU:

以下将每秒更新十次,不会“漂移”,也不会固定 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

回答by dbasnett

An experiment that shows that the timer should not be used for timing. It is good to use the timer to show the stopwatch elapsed time on a periodic basis.

一个实验表明定时器不应该用于计时。最好使用计时器来定期显示秒表经过的时间。

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