C#倒数计时器,没有准确性。寻找不同的方式来做到这一点

时间:2019-04-01 18:14:49

标签: c# uwp

我有一个倒数计时器,运行时它似乎每5-10秒落后1秒。 有什么方法可以使该倒数计时器精确到系统时钟时间?

Public MAIN()
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(1000);
            timer.Tick += timer_Tick;



void timer_Tick(object sender, object e)
{
            basetime = basetime - 1;
            txt.Text = string.Format("{0:00}:{1:00}:{2:00}", basetime / 3600, (basetime / 60) % 60, basetime % 60);
            if (basetime == 0)
            {
                timer.Stop();
                Timer_Start.IsEnabled = Timer_Pause.IsEnabled = Timer_Restart.IsEnabled = true;
            }
}

我想尝试一些不同的想法,而且我将不得不暂停并定期启动计时器,因此也必须将其应用于解决方案中。

2 个答案:

答案 0 :(得分:0)

与其尝试从迭代器中计算时间,不如使用系统时钟来计算时间。

basetime的类型更改为DateTime

启动计时器时,请设置基准时间:basetime = DateTime.Now; 并将TimeSpan变量设置为倒数时间:countdown = new TimeSpan(/*your code here*/);

现在像这样更新您的timer_Tick

void timer_Tick (object sender, object e)
{
    var now = DateTime.Now;

    // This computes the remaining time and formats it for display
    txt.Text = (now - basetime).ToString("hh:mm:ss");

    // Checks that the timer is complete
    if (now - basetime > countdown)
    {
        /* stop the timer */
    }
}

DispatcherTimer并不是十分准确,它是近似值,对于大多数任务来说已经足够了,但是跟踪时间是不够的。相反,您可以使用它大约一秒钟,然后使用系统时钟中的实际时间更新计时器。

答案 1 :(得分:0)

解决方案;

运行秒表并将其与数学进行比较。

P.S。我知道有更好的方法可以这样做,并且可能会在将来的版本中更新。


        void Timer_Tick(object sender, object e)
         {
            int BaseINMill = basetime * 1000;
            //total of milliseconds left
            basetimeMILL.Text = BaseINMill.ToString() ;
            //Display the total Milliseconds elapsed
            ConsolePost.Text = VerifyMill.ElapsedMilliseconds.ToString();


            if( CorrectionWatch.ElapsedMilliseconds >= 2000)
            {
                PreCorrBaseTime = PreCorrBaseTime - 2;

                //Display the Correction timer Milliseconds elapsed
                Correctiontest.Text = CorrectionWatch.ElapsedMilliseconds.ToString();
                CorrectionWatch.Restart();
                //Show the total time between seconds changing on screen
                ConsoleOutputPre.Text = stopwatch.ElapsedMilliseconds.ToString();
                basetime = PreCorrBaseTime;
                txt.Text = string.Format("{0:00}:{1:00}:{2:00}", basetime / 3600, (basetime / 60) % 60, basetime % 60);
                if (basetime == 0)
                {
                    timer.Stop();
                    Timer_Start.IsEnabled = Timer_Pause.IsEnabled = Timer_Restart.IsEnabled = true;
                    VerifyMill.Stop();
                }
                stopwatch = Stopwatch.StartNew();
            }
            else {
                if (stopwatch.ElapsedMilliseconds >= 975 && stopwatch.ElapsedMilliseconds <=1025 )
                {
                    //Show the total time between seconds changing on screen
                    ConsoleOutputPre.Text = stopwatch.ElapsedMilliseconds.ToString();
                    basetime = basetime - 1;
                    txt.Text = string.Format("{0:00}:{1:00}:{2:00}", basetime / 3600, (basetime / 60) % 60, basetime % 60);
                    if (basetime == 0)
                    {
                        timer.Stop();
                        Timer_Start.IsEnabled = Timer_Pause.IsEnabled = Timer_Restart.IsEnabled = true;
                        VerifyMill.Stop();
                    }
                    stopwatch = Stopwatch.StartNew();
                }

                if (stopwatch.ElapsedMilliseconds >= 1026 && stopwatch.ElapsedMilliseconds <= 2000)
                {
                    //Show the total time between seconds changing on screen
                    ConsoleOutputPre.Text = stopwatch.ElapsedMilliseconds.ToString();
                    basetime = basetime - 1;
                    txt.Text = string.Format("{0:00}:{1:00}:{2:00}", basetime / 3600, (basetime / 60) % 60, basetime % 60);
                    if (basetime == 0)
                    {
                        timer.Stop();
                        Timer_Start.IsEnabled = Timer_Pause.IsEnabled = Timer_Restart.IsEnabled = true;
                        VerifyMill.Stop();
                    }
                    stopwatch = Stopwatch.StartNew();
                }
                if (stopwatch.ElapsedMilliseconds > 2000)
                {
                    ErrorPrompt();
                    VerifyMill.Stop();
                }
            }


        }