Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / C#
Tip/Trick

Keep Alive Timer using DispatcherTimer

Rate me:
Please Sign up or sign in to vote.
4.75/5 (10 votes)
26 Aug 2016CPOL2 min read 13.2K   133   11   2
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:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
SuggestionDateTime.Now versus DateTime.UtcNow Pin
sx200829-Aug-16 7:59
sx200829-Aug-16 7:59 
It would be better to use DateTime.UtcNow instead of DateTime.Now.
The property UtcNow is multiple times faster and free of glitches while the OS switches from winter to summer time.
AnswerRe: DateTime.Now versus DateTime.UtcNow Pin
Clifford Nelson29-Aug-16 9:00
Clifford Nelson29-Aug-16 9:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.