лучший способ сделать простой и точный секундомер - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть проект, который я должен сделать секундомер. Это работает, но не точно по сравнению с таймером Windows. Кроме того, я хочу знать, есть ли другой эффективный и простой способ сделать это, если так, как я могу сделать это ?. Интервал таймера равен 1.

Вот мой код:

    Dim min As Integer = 30
    Dim seg As Integer = 59
    Dim mseg As Integer = 99
    Private Sub tmTimer_Tick(sender As Object, e As EventArgs) Handles tmTimer.Tick

        If lblStopWatch.Text = "00:00:00" Then
            lblStopWatch.ForeColor = Color.DarkGray
            tmTimer.Enabled = False
            min = 30
            seg = 59
            mseg = 99
        Else
            mseg -= 1
            If mseg < 0 Then
                mseg = 99
                seg -= 1
                If seg < 0 Then
                    seg = 59
                    min -= 1
                End If
            End If

            If min < 10 And seg < 10 And mseg < 10 Then
                lblStopWatch.Text = "0" + min.ToString + ":0" + seg.ToString + ":0" + mseg.ToString
            ElseIf min < 10 And seg < 10 Then
                lblStopWatch.Text = "0" + min.ToString + ":0" + seg.ToString + ":" + mseg.ToString
            ElseIf min < 10 And mseg < 10 Then
                lblStopWatch.Text = "0" + min.ToString + ":" + seg.ToString + ":0" + mseg.ToString
            ElseIf seg < 10 And mseg < 10 Then
                lblStopWatch.Text = min.ToString + ":0" + seg.ToString + ":0" + mseg.ToString
            Else
                If mseg < 10 Then
                    lblStopWatch.Text = min.ToString + ":" + seg.ToString + ":0" + mseg.ToString
                ElseIf seg < 10 Then
                    lblStopWatch.Text = min.ToString + ":0" + seg.ToString + ":" + mseg.ToString
                ElseIf min < 10 Then
                    lblStopWatch.Text = "0" + min.ToString + ":" + seg.ToString + ":" + mseg.ToString
                Else
                    lblStopWatch.Text = min.ToString + ":" + seg.ToString + ":" + mseg.ToString
                End If
            End If
        End If
    End Sub

А вот кнопка, которая может запустить таймер:

Private Sub btnAcept_Click(sender As Object, e As EventArgs) Handles btnAcept.Click

     lblCronometro.ForeColor = Color.RoyalBlue
        lblCronometro.Text = "30:00:00"
        tmCronometro.Enabled = True
        tmCronometro.Start()

End Sub

Если пример в C# или VB, я могу получить оба. Спасибо.

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

СОВЕТЫ

Если вы хотите сделать это самостоятельно, вместо использования существующего класса StopWatch, другим вариантом будет отслеживание времени запуска секундомера (start) и как долго работает секундомер (elapsed).

С помощью значения start мы можем вычислить время elapsed в событии таймера Tick, например:

// elapsed is a TimeSpan object
elapsed = DateTime.Now - start;

Если мы добавим возможность останавливать секундомер и затем запускать его снова (не сбрасывая), мы должны учитывать это «время простоя». Мы можем сделать это в нашем событии нажатия кнопки Start, вычитая время elapsed из текущего времени и используя это значение в качестве времени начала:

// start is a DateTime object
start = DateTime.Now.Subtract(elapsed);

Затем, когда мы хотим отобразить истекшее время для пользователя, мы можем просто использовать наше поле elapsed и отформатировать его следующим образом: hours:minutes:seconds.milliseconds, используя строку пользовательского формата.

// I noticed you're doing a countdown timer, so we want to display the difference
// between the original duration of 30 minutes and the elapsed time we've been running
lblStopwatch.Text = (duration - elapsed).ToString("hh\\:mm\\:ss\\.ff");

ОТВЕТ

Если этих подсказок недостаточно, вот пример проекта, использующего эту стратегию:

public partial class Form1 : Form
{
    private DateTime _startTime;
    private TimeSpan _elapsedTime;

    // The starting duration for the countdown timer
    private readonly TimeSpan _duration = TimeSpan.FromMinutes(30);

    public Form1()
    {
        InitializeComponent();
        ResetTimer();
    }

    private void ResetTimer()
    {
        _startTime = DateTime.Now;
        _elapsedTime = TimeSpan.Zero;
        UpdateStopwatchDisplay();
    }

    private void UpdateStopwatchDisplay()
    {
        // Display the current duration to the user
        lblStopwatch.ForeColor = timer1.Enabled ? Color.RoyalBlue : Color.DarkGray;
        lblStopwatch.Text = (_duration - _elapsedTime).ToString("hh\\:mm\\:ss\\.ff");
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        // Subtract 'elapsed' from 'now' to account for any stoppage time
        _startTime = DateTime.Now.Subtract(_elapsedTime);
        UpdateStopwatchDisplay();
        timer1.Start();
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        timer1.Stop();
        UpdateStopwatchDisplay();
    }

    private void btnReset_Click(object sender, EventArgs e)
    {
        ResetTimer();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        // Update elapsed time
        _elapsedTime = DateTime.Now.Subtract(_startTime);

        // Stop the timer if we've reached our duration
        if (_elapsedTime >= _duration)
        {
            _elapsedTime = _duration;
            timer1.Stop();
        }

        UpdateStopwatchDisplay();
    }
}
0 голосов
/ 23 апреля 2020

. NET Framework включает в себя класс Stopwatch, поэтому вы должны его использовать. Это совершенно точно, по крайней мере, в той степени, в которой ваш код выполняет свои методы вовремя. У него есть методы Start, Stop, Restart и Reset, и он предоставляет истекшее время в виде TimeSpan, которое можно форматировать напрямую вместо всей этой конкатенации. Единственное, для чего вы используете Timer, - это отображение текущего истекшего времени в Label. Например,

Private ReadOnly stopwatch As New Stopwatch

Private Sub startButton_Click(sender As Object, e As EventArgs) Handles startButton.Click
    DisplayElapsedTime()

    stopwatch.Start()
    displayTimer.Start()

    startButton.Enabled = False
    stopButton.Enabled = True
    restartButton.Enabled = True
    resetButton.Enabled = False
End Sub

Private Sub stopButton_Click(sender As Object, e As EventArgs) Handles stopButton.Click
    stopwatch.Stop()
    displayTimer.Stop()

    DisplayElapsedTime()

    startButton.Enabled = True
    stopButton.Enabled = False
    restartButton.Enabled = False
    resetButton.Enabled = True
End Sub

Private Sub restartButton_Click(sender As Object, e As EventArgs) Handles restartButton.Click
    stopwatch.Restart()

    DisplayElapsedTime()
End Sub

Private Sub resetButton_Click(sender As Object, e As EventArgs) Handles resetButton.Click
    stopwatch.Reset()

    DisplayElapsedTime()
End Sub

Private Sub displayTimer_Tick(sender As Object, e As EventArgs) Handles displayTimer.Tick
    DisplayElapsedTime()
End Sub

Private Sub DisplayElapsedTime()
    elapsedTimeLabel.Text = stopwatch.Elapsed.ToString("m\:ss\.fff")
End Sub
...