Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Keep Alive Timer using DispatcherTimer

0.00/5 (No votes)
26 Aug 2016 1  
A simple timer that will expire if it is not nudged within a certain time. This will cause an Action to be executed.

Introduction

I had a case where I was creating undo/redo functionality for a pan and zoom control. For a lot of the actions I could let the action happen and save the details on the stack, but there was the zooming using the mouse scroll button, and the fixed zoom in, zoom out, paging and arrow key actions that I did not think it made sense to store every action. I looked around for a timer that somebody may have created to do this task, and did not find anything, so I created my own.

The Code

The code is pretty basic:

public class KeepAliveTimer
{
    private readonly DispatcherTimer _timer;
    private DateTime _startTime;
    private TimeSpan? _runTime;

    public TimeSpan Time { get; set; }
    public Action Action { get; set; }
    public bool Running { get; private set; }

    public KeepAliveTimer(TimeSpan time, Action action)
    {
        Time = time;
        Action = action;
        _timer = new DispatcherTimer(DispatcherPriority.ApplicationIdle) { Interval = time };
        _timer.Tick += TimerExpired;
    }

    private void TimerExpired(object sender, EventArgs e)
    {
        lock (_timer)
        {
            Running = false;
            _timer.Stop();
            _runTime = DateTime.UtcNow.Subtract(_startTime);
            Action();
        }
    }

    public void Nudge()
    {
        lock (_timer)
        {
            if (!Running)
            {
                _startTime = DateTime.UtcNow;
                _runTime = null;
                _timer.Start();
                Running = true;
            }
            else
            {
                //Reset the timer
                _timer.Stop();
                _timer.Start();
            }
        }
    }

    public TimeSpan GetTimeSpan()
    {
        return _runTime ?? DateTime.UtcNow.Subtract(_startTime);
    }
}

The Nudge method is called which starts the timer, the Running property is set to true and the time is saved. Each time the Nudge is called, the timer is restarted. If the timer expires, then the timer is stopped, the Action provided by the user is executed, the Running property is set to false, and the time the timer was active is saved.

The GetTimeSpan method will either get the TimeSpan for the last run if the timer is not running, or the TimeSpan since the timer started.

Using the code

Using the timer is very easy:

_timer = new KeepAliveTimer(TimeSpan.FromMilliseconds(500), () =>
    {
        ResultTextBlock.Text = $"You lasted {_timer.GetTimeSpan()
    .TotalSeconds.ToString("0.000")} seconds";
        BombImage.Visibility = Visibility.Visible;
    });
MouseWheel += (s, e) =>
    {
        _timer.Nudge();
        BombImage.Visibility = Visibility.Collapsed;
        IntroductionTextBlock.Visibility = Visibility.Collapsed;
        WarningTextBlock.Visibility = Visibility.Visible;
    };

 Just have to initialize an instance with the TimeSpan that will indicated how long since the last nudge to wait before the timer is considered expired, and the Action to execute when the timer expires.

The Sample

I just used the concept of requireing the user to continue to use the mouse scroll wheel, and if the user fails to continue to scroll the scroll wheel, a bomb explodes. The user is informed of how long he was scrolling.

This is the initial screen that the user will see. It basiclly tells the user to start using the scroll button on the mouse

This screen shows what happens when the user starts scrolling the mouse scroll wheel. If the user stops...

This screen shows the bomb exploding, telling the user that he has to keep scrolling the scroll button. The message on the bottom tells the user how long they were scrolling.

The last screen shows what it looks like when the user is scrolling. There is no bomb image since the user has not stopped scrolling. The time at the bottom is the time the user kept scrolling the previous time.

History

  • 2016-08-26: Initial version
  • 2016-08-29: Moved from using DateTime.Now to DateTime.UtcNow as suggested.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here