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

Defer Any Algorithm

0.00/5 (No votes)
23 Jun 2013 1  
Defer algorithms to run once within a given time span

Introduction

This idea was thought up by a colleague of mine at work by the name of Greg. It is a wonderful idea that will allow you to defer logic of any algorithm you write. This can be extremely helpful if you design visual controls and use events to drive your control. Custom drawing algorithms can benefit greatly from this.

Using the Code

Here is the base class that helps drive this...

/// <summary>Enforces that an operation will only happen
    /// one time within a given time span.</summary>
public class DelayedSingleActionInvoker : DispatcherObject
{
    #region Private Properties
    private Action ActionToInvoke { get; set; }
    private DispatcherOperation LastOperation { get; set; }
    private DispatcherPriority Priority { get; set; }
    private DispatcherTimer Timer { get; set; }
    #endregion

    #region Constructors
    /// <summary>Initializes a new instance of DelayedSingleActionInvoker.
    /// TimeSpan is half a second.</summary>
    /// <param name="action">The action to execute.</param>
    public DelayedSingleActionInvoker(Action action)
    {
        ActionToInvoke = action;
        Priority = DispatcherPriority.Background;

        Timer = new DispatcherTimer(Priority, Dispatcher);
        Timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
        Timer.Tick += Tick;
    }

    /// <summary>Initializes a new instance of DelayedSingleActionInvoker.</summary>
    /// <param name="action">The action to execute.</param>
    /// <param name="waitSpan">The amount of time to wait
    /// for the action to be relistened for before firing.</param>
    public DelayedSingleActionInvoker(Action action, TimeSpan waitSpan)
    {
        ActionToInvoke = action;
        Priority = DispatcherPriority.Background;

        Timer = new DispatcherTimer(Priority, Dispatcher);
        Timer.Interval = waitSpan;
        Timer.Tick += Tick;
    }

    /// <summary>Initializes a new instance of DelayedSingleActionInvoker.</summary>
    /// <param name="action">The action to execute.</param>
    /// <param name="waitSpan">The amount of time to wait
    /// for the action to be relistened for before firing.</param>
    /// <param name="priority">The priority.</param>
    public DelayedSingleActionInvoker(Action action, TimeSpan waitSpan, DispatcherPriority priority)
    {
        ActionToInvoke = action;
        Priority = priority;

        Timer = new DispatcherTimer(Priority, Dispatcher);
        Timer.Interval = waitSpan;
        Timer.Tick += Tick;
    }
    #endregion

    #region Events
    private void Tick(object sender, EventArgs e)
    {
        LastOperation = Dispatcher.BeginInvoke((Action)delegate
        {
            Timer.Stop();

            ActionToInvoke.Invoke();

            LastOperation = null;
        }, Priority);
    }
    #endregion

    #region Public Methods
    /// <summary>Begins invoking the action.</summary>
    public void BeginInvoke()
    {
        if (Timer.IsEnabled) Timer.Stop();

        if (LastOperation != null)
            LastOperation.Abort();

        Timer.Start();
    }
    #endregion
}

Here is a perfect example...

public partial class MainWindow : Window
{
    private DelayedSingleActionInvoker SizeChangedInvoker { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        SizeChanged += Window_SizeChanged;
        SizeChangedInvoker = new DelayedSingleActionInvoker(SizeChangedLogic);
    }

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        SizeChangedInvoker.BeginInvoke();
    }

    private void SizeChangedLogic()
    {
        Debug.WriteLine("SizeChanged goodness");
    }
}

That is just a WPF application project in Visual Studio.

Run your main window and resize it for a few seconds and watch as the message fires half a second after you stop resizing the window.

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