Timer multiple call

BeginnnnnerBeginnnnner Member ✭✭

Hi :)
I'm facing a problem with timer. I tried to make a countdown (from 60s to zero) and everything works fine when I first call the method, but when I call it second time, it goes twice as fast and so on... How to fix it?
method Casomira simply means Countdown
Here is my code:

This didn't work: timer set to null, timer autoreset...
tried to find it everywhere

Answers

  • AlmaJensen.9398AlmaJensen.9398 USMember ✭✭✭

    I don't see the exact cause of your issue. But here's a snippet of timer code I have running in one of my Xamarin Forms applications.

    private TimeSpan timeout { get; set; }
    private bool timerrunning;
    public string Timeout { get; set; }
    private readonly TimeSpan timeoutLimit = TimeSpan.FromMinutes(10);

        internal void ResetTimer()
        {
            timerrunning = true;
            timeout = timeoutLimit;
    
            UpdateTimerUI();
        }
    
        internal void StartTimer()
        {
            ResetTimer();
    
            Device.StartTimer(TimeSpan.FromSeconds(1), () =>
            {
                UpdateTimerUI();
                CheckTimeout();
                return timerrunning;
            });
        }
    
        internal void CheckTimeout()
        {
            if (timeout <= new TimeSpan())
            {
                ReportPickTimeoutCancelled(true);
    
                StopTimer();
                Logout();
            }
        }
    
        internal void StopTimer()
        {
            timerrunning = false;
        }
    
        internal void UpdateTimerUI()
        {
    
            timeout = timeout.Subtract(TimeSpan.FromSeconds(1));
            Timeout = timeout.ToString(@"mm\:ss");
        }
    
  • JamesLaveryJamesLavery GBBeta, University ✭✭✭✭✭
    I think both these approaches fall into the trap of assuming that a timer will trigger its update event at exactly the interval if the timer.

    My experience is that the timer update event may trigger at or after the interval.

    Therefore you can't set a 1 second interval and just decrement a counter at each update event.

    I don't have the code to hand but my approach is:

    Save the start time.
    Create a timer with an interval at which to check and update the UI.
    In the update event:
    Calculate elapsed= now-start time.
    Update the UI
    Stop the timer if elapsed is > limit
  • PaulNTUPaulNTU USMember ✭✭✭
    edited February 6

    @JamesLavery is correct. For an accurate timer you will want to check it against a stored start time for accuracy.
    A quick dirty example is below

            /// <summary>
            /// Count down timer
            /// </summary>
            /// <param name="countdownms">Count down time in milliseconds</param>
            private void StartTimer(int countdownms)
            {
                DateTime starttime = DateTime.Now;
    
                Xamarin.Forms.Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
                    {
    
                        TimeSpan diff = DateTime.Now - starttime;
                        if (diff.Milliseconds > countdownms)                        {
                            // Finished
    
                            // Cancel the timer, we are finished
                            return false;
                        }
                        else
                        {
                            // Continue counting down
                            int timeremainingsecs = (countdownms - diff.Milliseconds) / 1000;
    
                            // Keep the timer running. Will call again in 500ms
                            return true;
                        }
                    });
            }
    
  • PaulNTUPaulNTU USMember ✭✭✭

    In response to why its counting down faster with each call, it is because calling the function multiple times will create a new timer with each call to the function. Each timer will be counting down at the same time, and they are all altering the same variable. e.g. two calls is making two separate timers, each subtracting from your variable

    A solution to your code would be to keep track of the timer you have created. Each time you call your function you check to see if an existing timer is running, you either cancel it and start a new one or leave it running, depending on what functionality you want

    If you paste your code as text instead of an image I will tweak it to show you what I mean ;)

Sign In or Register to comment.