Home > Software engineering >  UI Performance - Xamarin
UI Performance - Xamarin

Time:01-13

Hey I have an rather specific issue.

I am building an metronom, and this metronom also shows boxes, which will change their color in the given tact in bpm. the highest possible bpm is 400bpm with 4/4 beats. that means the fastest change of color should happen every: 37,5 ms.

enter image description here

The change of color will last some milliseconds.

Until now i tried to realize that with a timer:

timer = new System.Timers.Timer() { AutoReset = true, SynchronizingObject = null };

        private async void timer1_Elapsed(object sender, ElapsedEventArgs e)
        {
            boxViewLast = (BoxView)beatDisplay.Children[(int)lastI];
            boxView = (BoxView)beatDisplay.Children[(int)i];
            boxViewLast.Color = boxColor;
            boxView.Color = transColor;
            await Task.Delay((int)BeatMilliseconds);
            boxView.Color = boxColor;
            lastI = i;
            i  ;
            if (i >= numOfChildren)
            {
                i = 0;
            }

            timer.AutoReset = Tempo == 1 && Play;
        }

But in the UI I see a flickering some times if the color is changing fast and sometimes it is not even changing. I guess that resources are getting blocked and so the change can not be fullfilled in the given time. Is there a way to have UI change async and very performant? But I also need a very pricise timer

CodePudding user response:

No reason to await Task.Delay inside the callback. You can use the timer to define the interval between callbacks:

var lastTime = DateTime.Now;
var times = new List<TimeSpan>(1000);
var timer = new System.Timers.Timer() { Enabled = true, Interval = 32, AutoReset = true};
timer.Elapsed  = TimerHandler;
Console.WriteLine("Starting timer");
timer.Start();
await Task.Delay(TimeSpan.FromSeconds(3));
timer.Stop();

foreach (var time in times)
{
    Console.WriteLine($"{time.TotalMilliseconds}ms passed");
}

void TimerHandler(object? sender, System.Timers.ElapsedEventArgs e)
{
    TimeSpan timePassed = e.SignalTime - lastTime;
    times.Add(timePassed);
    lastTime = DateTime.Now;
}

It's going to be somewhat accurate:

30.5771ms passed
31.0725ms passed
30.8268ms passed
31.0783ms passed
30.5758ms passed
31.4693ms passed
31.0038ms passed
32.1051ms passed
31.0289ms passed
31.1313ms passed
30.9087ms passed
31.0877ms passed
31.9015ms passed
30.7389ms passed
46.8875ms passed
31.4987ms passed
31.7549ms passed

CodePudding user response:

Thanks to @Jason, I used SkiaSharp which solved the issue with the flickering. It is more cleaner now. But the accuracy in time I could not solve yet.

  •  Tags:  
  • Related