Construction of timer

2

I am building a timer using WPF . When I ran some tests, I noticed that the timestamp in WPF lags behind the timer of my iPhone . The difference starts appearing after 8 seconds after the start of the timing.

Below I've made available the Timer_tick method code.

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 for 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 for 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 a lot of tutorials but I still can not get a timer where there is not so much time difference. I do not know if it is due to the WPF performance being considered smaller than the WinForm .

I had already done this same timer in WinForm and the time difference was imperceptible.

There is another problem, the timer is not displaying in the MM: SS: MMM format. I do not know if the .substring that I am applying in the label update is wrong or if interval is wrong.     

asked by anonymous 17.11.2017 / 22:46

2 answers

2

Use StopWatch in C #

    Stopwatch stopwatch = new Stopwatch();

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

In WPF you can do this, but you can improve this code a lot:

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;
    }
}
    
18.11.2017 / 13:14
0

This was the result. Adapted to my need. It worked very well. 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();
    }
}

}

    
20.11.2017 / 20:46