WPF Timer problem… Cannot get correct millisecond

2019-01-20 16:41发布

I have a basic question regarding timers. My timer is acting very strange. I am trying to make the tick occur every millisecond to update my data. I can get it to work with seconds, it seems, but not milliseconds..

I am using WPF and am wondering why the following is not functioning correctly.

It appears that the "second" countdown works correctly, but while using the same procedure and editing one value, it does not "tick" correctly it seems.

I am trying to make a millisecond countdown using the following:

            //TimeSpan temp0 = new TimeSpan(0, 0, 0, 0, 1);
        CountdownTimer = new DispatcherTimer();
        CountdownTimer.Tick += new EventHandler(Countdowntimer_Tick);
        CountdownTimer.Interval = TimeSpan.FromSeconds(1.0);//temp0;

The above seems like it works fine for a "second" countdown, but I need more precision, so I do the following:

            //TimeSpan temp0 = new TimeSpan(0, 0, 0, 0, 1);
        IntroCountdownTimer = new DispatcherTimer();
        IntroCountdownTimer.Tick += new EventHandler(Countdowntimer_Tick);
        IntroCountdownTimer.Interval = TimeSpan.FromSeconds(0.001);//temp0;

This would give us millisecond precision, BUT, when I try this in my program, it is much much slower. Any ideas why?

    void Countdowntimer_Tick(object sender, EventArgs e)
    {
        m_dIntroCountdown -= 1.0;
    }

ps: I do set the "m_dIntroCountdown accordingly. If we are in milliseconds, I set it to 5000.0, if in seconds, 5.0

Maybe I am looking too much into this.. any ideas?

All help is appreciated.

Thanks!

标签: wpf timer
3条回答
闹够了就滚
2楼-- · 2019-01-20 17:13

A 1 ms time resolution is way too fine for what WPF can handle. Even at 120 fps (which is high), you will only get 8.3 ms resolution. In order to update at 1ms, you'd need to render 1000 frames per second. This is just beyond the limits of any modern system. Even the human eye starts to lose track of discontinuous changes in motion at ~10ms.

What do you want the resolution for? If you are just trying to keep track of time, use System.Diagnostics.Stopwatch. It has ~10ns resolution.

查看更多
淡お忘
3楼-- · 2019-01-20 17:36

This is the code for C#:

using System.Windows.Threading;


public partial class MainWindow
{

    DateTime Time = new DateTime();
    DispatcherTimer timer1 = new DispatcherTimer();

    private void dispatchertimer_Tick(object sender, EventArgs e)
    {
        TimeSpan Difference = DateTime.Now.Subtract(Time);
        Label1.Content = Difference.Milliseconds.ToString();
        Label2.Content = Difference.Seconds.ToString();
        Label3.Content = Difference.Minutes.ToString();
    }

    private void Button1_Click(System.Object sender, System.Windows.RoutedEventArgs e)
    {
        timer1.Tick += new System.EventHandler(dispatchertimer_Tick);
        timer1.Interval = new TimeSpan(0, 0, 0);


        if (timer1.IsEnabled == true)
        {
            timer1.Stop();
        }
        else
        {
            Time = DateTime.Now;
            timer1.Start();

        }
    }

Here is how to do it:

Add 3 labels and 1 button : Label1, Label2, Label3 and Button1

This is the code for Vb(Visual Basic):

Imports System.Windows.Threading

Class MainWindow

Dim timer1 As DispatcherTimer = New DispatcherTimer()
Dim Time As New DateTime

Private Sub dispatchertimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
    Dim Difference As TimeSpan = DateTime.Now.Subtract(Time) 
    Label1.Content = Difference.Milliseconds.ToString
    Label2.Content = Difference.Seconds.ToString
    Label3.Content = Difference.Minutes.ToString
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
    AddHandler timer1.Tick, AddressOf dispatchertimer_Tick
    timer1.Interval = New TimeSpan(0, 0, 0)


    If timer1.IsEnabled = True Then
        timer1.Stop()
    Else
        Time = DateTime.Now
        timer1.Start()

    End If
End Sub
End Class
查看更多
我命由我不由天
4楼-- · 2019-01-20 17:39

DispatcherTimer is not an high precision timer - it's a low precision low accuracy timer suitable for UI work (where people don't notice delays of 100ms).

A high precision timers that execute code every 1ms is very difficult, maybe even impossible, to implement (what do you do if some other process in the system goes to 100% CPU and your process doesn't run for over 1ms? what do you do if the code executed by the time has to be reloaded from the page file and it takes more than 1ms?).

查看更多
登录 后发表回答