Click here to Skip to main content
15,892,298 members
Articles / Desktop Programming / WPF
Tip/Trick

Defer Any Algorithm

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
23 Jun 2013MIT 9K   7   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...

C#
/// <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...

C#
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, along with any associated source code and files, is licensed under The MIT License


Written By
Architect SL-X
United States United States
Developed various languages over the years. Found C# and fell in love with it. Been doing it ever since. Love WPF or ASP.Net MVC with the Razor view engine as front-end technologies. As a developer I want to make development easier for all developers. I like designing and providing tools for other programmers to use.

Comments and Discussions

 
QuestionNice Tip Pin
InfRes26-Jun-13 1:41
InfRes26-Jun-13 1:41 

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.