Archive for the ‘job’ tag
PostponingTimer
This is a small timer class that I have found useful a couple of times.
It takes a job and a timeout in its Run() method, which it executes
after the timeout, unless you call the Run() method again, in which
case it postpones the execution of the job. I have mostly used this
in connection with some type of user input. For instance, doing
something when there has been a sufficient pause in scrolling or typing.
/// <summary>
/// This class can be used to execute a job just once after a specified
/// time since the last of a series of events has fired.
/// For instance, when implementing an Auto-Save feature in a textbox you
/// might want to avoid saving on every keypress event. In this case you can
/// call Run(() => Save(), 5000) in each keypress event. The PostPoningTimer
/// will then make sure that Save() is executed one time when 5 seconds has
/// past since the last keypress event. Any new keypresses will of course
/// repeat the process.
/// </summary>
public class PostponingTimer
{
private Timer timer;
private Dispatcher CurrentDispatcher
{
get
{
#if SILVERLIGHT
return System.Windows.Deployment.Current.Dispatcher;
#else
return Dispatcher.CurrentDispatcher;
#endif
}
}
private void Execute(Action job, Dispatcher dispatcher)
{
#if SILVERLIGHT
dispatcher.BeginInvoke(job);
#else
dispatcher.Invoke(job);
#endif
}
/// <summary>
/// If you keep calling Run() within timeout, job never gets executed.
/// Only when you stop calling Run() job will run once after timeout
/// milliseconds.
/// <para>Job will run on calling threads dispatcher. If in silverlight
/// the UI threads dispatcher is used.</para>
/// </summary>
/// <param name=”job”></param>
/// <param name=”timeout”></param>
public void Run(Action job, int timeout)
{
//Make sure the timer from last call is prevented from running.
if (timer != null) timer.Dispose();
//When not in SILVERLIGHT the line below makes sure to use the
//dispatcher of the calling thread.
//In silverlight the UI thread dispatcher is used.
Dispatcher dispatcher = CurrentDispatcher;
timer = new Timer(new TimerCallback((o) =>
{
Execute(job, dispatcher);
}), null, timeout, Timeout.Infinite);
}
/// <summary>
/// If you keep calling Run() within timeout, job never gets executed.
/// Only when you stop calling Run() job will run once after timeout
/// milliseconds.
/// <para>Job will run on the timer’s thread.</para>
/// </summary>
/// <param name=”job”></param>
/// <param name=”timeout”></param>
public void RunNonUI(Action job, int timeout)
{
//Make sure the timer from last call is prevented from running.
if (timer != null) timer.Dispose();
timer = new Timer(new TimerCallback((o) =>
{
job();
}), null, timeout, Timeout.Infinite);
}
/// <summary>
/// If you keep calling Run() within timeout, job never gets executed.
/// Only when you stop calling Run() job will run once after timeout
/// milliseconds.
/// <para>Actions will run on calling threads dispatcher. If in
/// silverlight the UI threads dispatcher is used.</para>
/// </summary>
/// <param name=”job”></param>
/// <param name=”timeout”></param>
/// <param name=”callback”></param>
public void Run(Action job, int timeout, Action callback)
{
//Make sure the timer from last call is prevented from running.
if (timer != null) timer.Dispose();
//When not in SILVERLIGHT the line below makes sure to use the
//dispatcher of the calling thread.
//In silverlight the UI thread dispatcher is used.
Dispatcher dispatcher = CurrentDispatcher;
timer = new Timer(new TimerCallback((o) =>
{
Execute(job + callback, dispatcher);
}), null, timeout, Timeout.Infinite);
}
/// <summary>
/// If you keep calling Run() within timeout, job never gets executed.
/// Only when you stop calling Run() job will run once after timeout
/// milliseconds.
/// <para>Actions will run on the timer’s thread.</para>
/// </summary>
/// <param name=”job”></param>
/// <param name=”timeout”></param>
/// <param name=”callback”></param>
public void RunNonUI(Action job, int timeout, Action callback)
{
//Make sure the timer from last call is prevented from running.
if (timer != null) timer.Dispose();
timer = new Timer(new TimerCallback((o) =>
{
(job + callback)();
}), null, timeout, Timeout.Infinite);
}
}