Stopwatch construction

Asked

Viewed 1,855 times

2

I’m building a stopwatch using WPF. When I performed some tests, I realized that the timer on WPF is delayed in relation to my timer iPhone. The difference starts to appear from 8 seconds after the start of the timing.

Below I made available the method code Timer_tick.

private void Timer_Tick(object sender,EventArgs e)
{
        //lblTime.Content = DateTime.Now.ToLongTimeString();
        //lblTime.Content = DateTime.Now.ToString("HH:mm:ss:fff");

        //milliseconds++;
        //if (milliseconds >= 1000) {
        //    sec++;
        //    milliseconds = 0;
        //}
        //if (sec == 60) {
        //    min++;
        //    sec = 0;
        //}
        //lblTime.Content = string.Format("{0:00}:{1:00}:{2:D3}",min,sec,milliseconds);


        milliseconds += 15.560;

        if (milliseconds >= 1000) {
            milliseconds = 0;
            sec++;

            if (sec >= 60) {
                sec = 0;
                min++;
            }
        }

        lblTime.Content = min.ToString("00") + ":" + sec.ToString("00") + ":" +
            milliseconds.ToString("000").Substring(0,3);

        //lblTime.Content = String.Format("{0:00}:{1:00}:{2:000}", timer.Interval.Minutes, timer.Interval.Seconds, timer.Interval.Milliseconds);
    }

Below the code of the 'Start' button':

        private void Start(object sender,EventArgs e)
        {
          timer.Interval = TimeSpan.FromMilliseconds(1);
          timer.Tick += Timer_Tick;
          timer.Start();
        }

This is the code of the entire class:

public partial class MainWindow :Window
    {
        DispatcherTimer timer = new DispatcherTimer();

        int min = 0, sec = 0;
        double milliseconds = 0;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Timer_Tick(object sender,EventArgs e)
        {
            //lblTime.Content = DateTime.Now.ToLongTimeString();
            //lblTime.Content = DateTime.Now.ToString("HH:mm:ss:fff");

            //milliseconds++;
            //if (milliseconds >= 1000) {
            //    sec++;
            //    milliseconds = 0;
            //}
            //if (sec == 60) {
            //    min++;
            //    sec = 0;
            //}
            //lblTime.Content = string.Format("{0:00}:{1:00}:{2:D3}",min,sec,milliseconds);


            milliseconds += 15.560;

            if (milliseconds >= 1000) {
                milliseconds = 0;
                sec++;

                if (sec >= 60) {
                    sec = 0;
                    min++;
                }
            }

            lblTime.Content = min.ToString("00") + ":" + sec.ToString("00") + ":" +
                milliseconds.ToString("000").Substring(0,3);

            //lblTime.Content = String.Format("{0:00}:{1:00}:{2:000}", timer.Interval.Minutes, timer.Interval.Seconds, timer.Interval.Milliseconds);
        }

        private void Start(object sender,EventArgs e)
        {
            timer.Interval = TimeSpan.FromMilliseconds(1);
            timer.Tick += Timer_Tick;
            timer.Start();
        }
    }

I’ve tried several tutorials but still can’t get a stopwatch where there was so much time difference. I don’t know if it’s due to the performance of WPF be considered to be less than that of Winform.

I had already made this same stopwatch on Winform and the time difference was imperceptible.

There is another problem, the timer is not displaying in format MM:SS:MMM. I don’t know if the .substring that I’m applying to the label is wrong or if the interval is wrong.

  • 1

    What interval is set in timer ? 1ms ?

  • 1

    Why not use a Timespan instead of creating one?

  • 1

    guy.. will always delay.. Voce wants to tick 1 in 1 ms and the processing time is greater than that 1 ms between the ticks.. so there will always be this difference..

2 answers

2


Use the Stopwatch in the C#

    Stopwatch stopwatch = new Stopwatch();

    stopwatch.Start();
    for (; ;)
    {
        Console.WriteLine(stopwatch.Elapsed);
    }

In WPF you can do so, but it can greatly improve this code:

public partial class MainWindow : Window
{
    private Stopwatch stopwatch = new Stopwatch();
    private Timer timer;
    private DispatcherTimer dispatcherTimer;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        stopwatch.Stop();
        dispatcherTimer.Stop();
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        stopwatch.Start();
        dispatcherTimer = new DispatcherTimer();
        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 10);
        dispatcherTimer.Start();
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        lblTimer.Content = stopwatch.Elapsed;
    }
}

0

This was the result. Adapted to my need. It worked great. using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading;

namespace Stopwatchwpf { public partial class Mainwindow :Window { Dispatchertimer dt = new Dispatchertimer(); Stopwatch sw = new Stopwatch(); string currentTime = string.Empty;

    public MainWindow()
    {
        InitializeComponent();
        dt.Tick += new EventHandler(dt_Tick);
        dt.Interval = new TimeSpan(0,0,0,0,1);
    }

    private void dt_Tick(object sender,EventArgs e)
    {
        if (sw.IsRunning) {
            TimeSpan ts = sw.Elapsed;
            currentTime = String.Format("{0:00}:{1:00}:{2:000}",
            ts.Minutes,ts.Seconds,ts.Milliseconds);
            lblTime.Content = currentTime;
        }
    }

    private void Start(object sender,RoutedEventArgs e)
    {
        sw.Start();
        dt.Start();
    }

    private void Stop(object sender,RoutedEventArgs e)
    {
        if (sw.IsRunning) {
            sw.Stop();
        }
        elapsedtimeitem.Items.Add(currentTime);
    }

    private void Lap(object sender,RoutedEventArgs e)
    {
        elapsedtimeitem.Items.Add(currentTime);
        sw.Reset();
        lblTime.Content= "00:00:000";
        sw.Start();
    }
}

}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.