Reputation: 129
I would like to create a global timer in .NET MAUI that synchronizes to the screen refresh rate. The purpose is to allow me to run my custom UI animations off of it by subscribing their update functions to the global timer Tick
event. The timer could also calculate deltaTime
between its updates by comparing DateTime.Now
at each Tick
.
I have written it as:
public class GlobalTicker {
//delta time solver:
public float deltaTime = 0f;
DateTime deltaTimeDateTime = DateTime.UtcNow;
//app run time:
public float appRunTime = 0f;
//UPDATE TIMER;
public IDispatcherTimer timer;
//SCREEN MONITOR:
private float refreshRate = 120f;
public GlobalTicker() {
//get init screen info:
refreshRate = DeviceDisplay.Current.MainDisplayInfo.RefreshRate;
//make timer
timer = Application.Current.Dispatcher.CreateTimer();
timer.Interval = TimeSpan.FromSeconds(1 / refreshRate); //run every 1/120 seconds or 1/60 seconds or so depending on refresh rate
timer.IsRepeating = true;
timer.Tick += (s, e) => tickPassed();
timer.Start();
}
public void tickPassed() {
MainThread.BeginInvokeOnMainThread(() => {
deltaTime = (float)(DateTime.UtcNow - deltaTimeDateTime).TotalSeconds;
appRunTime += deltaTime;
deltaTimeDateTime = DateTime.UtcNow;
Debug.WriteLine("TICK RATE " + 1 / deltaTime + " REFRESH RATE " + refreshRate + " TIMER INTERVAL RATE " + 1f / timer.Interval.TotalSeconds);
});
}
}
I stored the timer in the default Maui project MainPage.xaml.cs
file as:
public partial class MainPage : ContentPage {
public GlobalTicker globalTicker;
public MainPage() {
globalTicker = new();
InitializeComponent();
}
This seems logical to me, but I am getting Debug output in this otherwise empty default project like this:
TICK RATE 31.140133 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 29.039968 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 31.953068 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 53.155014 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 32.066185 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 29.648605 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 31.816835 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 53.06053 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 31.891823 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 32.210476 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
TICK RATE 46.126526 REFRESH RATE 59 TIMER INTERVAL RATE 59.00018290056698
In other words, the tick rate is no where near synchronized to the refresh rate. The timer Interval rate and refresh rate are being read and set as ~59 both the same. But I'm only getting ticks at 29-53 fps with broad variation.
The CPU strain in the project is virtually zero as it is an empty project. How might I get a proper timer update synchronized to the refresh rate? What is the reason it is not synchronizing now?
Thanks for any help.
EDIT
Found this that might solve it - method for high resolution timer: Most accurate timer in .NET?
Upvotes: 0
Views: 823