Tag Archives: Extension Method

Dispatcher.DelayedInvoke

There are many cases when a developer wants a delayed action to occur. This may be a simple timed reaction to a user event, a web service poll or retry loop, or any variety of task. If you’re feeling creative you could use a Storyboard or a complicated thread implementation, but I’d like to share an elegant solution that allows you to write delayed invokes on the UI thread like this:

Dispatcher.DelayedInvoke(TimeSpan.FromSeconds(30), () => { DoStuff(); });

This syntax is possible by leveraging the Extension Method notation. For those unfamiliar with extension methods, the general idea is that it is possible to define a static function where the first parameter is defined with a “this” keyword in front of it. This indicates to the compiler that any instance of the type of that first parameter should have the function applied to it. For example:

// Note the "this" prefix before the type specification.
public static string GetFullName(this User user)
{
	return String.Format("{0}, {1} {2}",
		user.LastName, user.FirstName, user.MiddleInitial);
}

public void TestFunction()
{
	User user = new User("John", String.Empty, "Doe");
	string fullName = user.GetFullName();
}

The real power of these extension methods is that you can add additional functionality to objects that are externally instantiated or that aren’t inheritable. The Dispatcher class is a perfect example of both. It is a sealed class, and the Dispatcher references exposed through the property on DependencyObjects is instantiated by the framework.

Getting back to the issue of the DelayedInvoke extension method, I decided to use a Thread with Sleep implementation so as not to use up a ThreadPool thread. There are many ways to implement a wait, and you can easily swap in another approach. Here is my full implementation:

public static class DispatcherExtensions
{
    // Invocation without arguments.
    public static void DelayedInvoke(this Dispatcher dispatcher, TimeSpan delay, Action action)
    {
        Thread thread = new Thread(DoDelayedInvokeByAction);
        thread.Start(new Tuple<Dispatcher, TimeSpan, Action>(dispatcher, delay, action));
    }

    private static void DoDelayedInvokeByAction(object parameter)
    {
        Tuple<Dispatcher, TimeSpan, Action> parameterData = (Tuple<Dispatcher, TimeSpan, Action>)parameter;

        Thread.Sleep(parameterData.Item2);

        parameterData.Item1.BeginInvoke(parameterData.Item3);
    }

    // Invocation with arguments.
    public static void DelayedInvoke(this Dispatcher dispatcher, TimeSpan delay, Delegate d, params object[] args)
    {
        Thread thread = new Thread(DoDelayedInvokeByDelegate);
        thread.Start(new Tuple<Dispatcher, TimeSpan, Delegate, object[]>(dispatcher, delay, d, args));
    }

    private static void DoDelayedInvokeByDelegate(object parameter)
    {
        Tuple<Dispatcher, TimeSpan, Delegate, object[]> parameterData = (Tuple<Dispatcher, TimeSpan, Delegate, object[]>)parameter;

        Thread.Sleep(parameterData.Item2);

        parameterData.Item1.BeginInvoke(parameterData.Item3, parameterData.Item4);
    }
}

It’s important to note that the thread work function calls the Dispatcher‘s BeginInvoke function. The main reason for exposing the DelayedInvoke function as an extension of the Dispatcher is that it is implicit that the callback be performed on the UI thread. Even when the DelayedInvoke function is called from a non-UI thread, all operations performed in the supplied delegate can be safely made against UI objects because of the Dispatcher.BeginInvoke call.

Hopefully this makes your life a little easier.