Asynchronous Commands in Metro, WPF & Silverlight

I’ve seen quite a few examples demonstrating the new async/await language features (C# 5 & VB next) with button click events;

private async void button1_Click(object sender, RoutedEventArgs e)
{
    string url = "http://reedcopsey.com";
    string content = await new WebClient().DownloadStringTaskAsync(url);
    this.textBox1.Text = string.Format("Page {0} supports XHTML 1.0: {1}",
      url, content.Contains("XHTML 1.0"));
}

If you are using an architectural pattern like MVVM it’s unlikely that you’re writing code like this. In WPF, Silverlight & Metro you can bind buttons directly to an object implementing the ICommand interface.

// WPF ICommand interface
public interface ICommand
{
    /// <summary>
    /// Defines the method to be called when the command is invoked.
    /// </summary>
    /// <param name="parameter">Data used by the command.
    /// If the command does not require data to be passed, this object can be set to null.</param>
    void Execute(object parameter);

    /// <summary>
    /// Defines the method that determines whether the command can execute in its current state.
    /// </summary>
    /// 
    /// <returns>
    /// true if this command can be executed; otherwise, false.
    /// </returns>
    /// <param name="parameter">Data used by the command.
    /// If the command does not require data to be passed, this object can be set to null.</param>
    bool CanExecute(object parameter);

    /// <summary>
    /// Occurs when changes occur that affect whether or not the command should execute.
    /// </summary>
    event EventHandler CanExecuteChanged;
}

The nice thing about commands vs. a simple click event is that they encapsulate the logic informing the button wether or not it can be executed. This is particularly useful when we start talking about asynchronous operations as we might like to disable the button while the asynchronous request is in flight.

Example

    public bool CanExecute(object parameter)
    {
        return !isExecuting;
    }

    public async void Execute(object parameter)
    {
        isExecuting = true;
        OnCanExecuteChanged();
        try
        {
            // await some asynchronous operation
        }
        finally
        {
            isExecuting = false;
            OnCanExecuteChanged();
        }
    }

What About Errors?

Note that commands are generally executed by the UI frameworks message loop, meaning that any unhandled exceptions will be posted onto the relevant synchronisation context.

AsyncCommand

This pattern is easily captured in a reusable object that we can use to build all our asynchronous commands.

    // a reusable asynchronous command
    public class AsyncCommand : ICommand
    {
        private readonly Func<Task> execute;
        private readonly Func<bool> canExecute;
        private bool isExecuting;

        public AsyncCommand(Func<Task> execute) : this(execute, () => true) { }

        public AsyncCommand(Func<Task> execute, Func<bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            // if the command is not executing, execute the users' can execute logic
            return !isExecuting && canExecute();
        }

        public event EventHandler CanExecuteChanged;

        public async void Execute(object parameter)
        {
            // tell the button that we're now executing...
            isExecuting = true;
            OnCanExecuteChanged();
            try
            {
                // execute user code
                await execute();
            }
            finally
            {
                // tell the button we're done
                isExecuting = false;
                OnCanExecuteChanged();
            }
        }

        protected virtual void OnCanExecuteChanged()
        {
            if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs());
        }
    }

Usage

In your view model you can now create asynchronous commands like this;

// example command, simulate an operation that takes 2 seconds.
new AsyncCommand(() => TaskEx.Delay(2000));

// example command, with some custom can execute logic
new AsyncCommand(() => TaskEx.Delay(2000), () => IsValidInput());

 

Memory Leaks

A word of warning… If your command object’s lifetime extends beyond that of the UI element (Button) that is subscribing to the CanExecuted event you should implement a weak event pattern in here. I think that is outside the scope of this article. I’ll follow up shortly.

In Conclusion

This is a great example of why async void methods are required in C#. Commands are like a bridge between synchronous UI elements like buttons and your view models asynchronous operations like web requests. Enjoy!

Hosting your own poker tournament with LINQPad & Reactive Extensions

Playing poker next Saturday night & want to impress your friends with your programming skills?

The following solution requires LINQPad Beta release; It uses the new DumpLive feature allowing you to render reactive streams of WPF UI Elements!

Enjoy!

(from round in new[]
{
    new{Small = 5, Big = 10, Length = 16},
    new{Small = 10, Big = 20, Length = 20},
    new{Small = 20, Big = 40, Length = 20},
    new{Small = 100, Big = 200, Length = 20},
    new{Small = 300, Big = 600, Length = 20},
    new{Small = 600, Big = 1200, Length = 20},
    new{Small = 1000, Big = 2000, Length = 20},
    new{Small = 5000, Big = 10000, Length = 20},
    new{Small = 30000, Big = 60000, Length = 20},
    new{Small = 100000, Big = 200000, Length = 20},
}   
let ts = TimeSpan.FromMinutes(round.Length)
select from tick in Observable.Interval(TimeSpan.FromSeconds(1)).TakeUntil(Observable.Timer(ts))
let remaining = ts.Subtract(TimeSpan.FromSeconds(tick))
select new{
    text = string.Format("Small: {0}\r\nBig: {1}\r\nRemaining: {2}", round.Small, round.Big, remaining),
    colour = remaining < TimeSpan.FromMinutes(1) ? Brushes.Red : Brushes.Black
})
.Concat()
.ObserveOnDispatcher()
.Select(x => new TextBlock{Text = x.text, FontSize = 80, Foreground = x.colour})
.DumpLive();

OUTPUT

image

Rxx 1.3 Released (Rx Contribution Project)

See; http://rxx.codeplex.com/

There are lots of new features, fixes & improvements. Release notes here;

http://rxx.codeplex.com/wikipage?title=Release%20Notes

Reactive Extensions 2.0 Beta: Portable Libraries

Further to my last post about Rx 2.0 assemblies.

Have you ever worked on a project that required shared contracts between different Microsoft platforms? For example you might have the following architecture;

image

Speaking from experience, this can become quite painful as you need a “multi-targeted compilation strategy”. Good news! .NET 4.5 allows you to create “portable class libraries” that work on multiple .NET Framework platforms.

The even better news is that this has not been neglected by the Rx team. This diagram shows you which Rx assemblies can be referenced by your own portable class libraries.

image

Presumably this means you can create libraries of Rx operators and share them between metro, desktop, phone & xbox applications. That’s awesome!

*UPDATE* I wonder if people would be interested in a portable version of Rxx.

Reactive Extensions 2.0 Beta: Assembly References

Before you jump into Rx 2.0 Beta you should know about some of the changes to the hierarchy of assemblies.

Rx 1.0 assemblies were structured like this;

image

 

Rx 2.0 assemblies are structured like this;

image

The big change here is the addition of the System.Reactive.Interfaces & System.Reactive.PlatformServices.

I’m guessing that the thinking behind this change but;

System.Reactive.Interfaces

This will allow people to define “service contracts” without bringing in the entire Rx stack.

System.Reactive.PlatformServices

This eliminates a hard dependency on platform specific scheduling, concurrency & timing including low level components such as the thread pool & high resolution timers.

More soon
James

Reactive Extensions 2.0 Beta

Rx – Awaiting events & observables in C# 5

So everyone is now using C# 5 to write asynchronous methods to await tasks right ;)

Did you know you can also await other things? Like events & observables!?

The following code demonstrates how you can “await” items being added to an observable collection.

using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Reactive;
using System.Reactive.Linq;

namespace ConsoleApplication11
{
    class Program
    {
        private static readonly ObservableCollection<int> Collection = new ObservableCollection<int>();

        static void Main()
        {
            Test();
            Collection.Add(42);
        }

        public static async void Test()
        {
            Console.WriteLine("awaiting event...");
            var itemsAdded = await 
                (
                    from collectionChanged in Collection.ToNotifyCollectionChangedObservable()
                    where collectionChanged.EventArgs.Action == NotifyCollectionChangedAction.Add
                    select collectionChanged.EventArgs.NewItems
                )
                .Take(1);

            Console.WriteLine("items added;");
            foreach (var item in itemsAdded)
                Console.WriteLine(item);
        }
    }

    public static class Extensions
    {
        public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>> 
            ToNotifyCollectionChangedObservable(this INotifyCollectionChanged source)
        {
            return Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
                (h => source.CollectionChanged += h,
                h => source.CollectionChanged -= h);
        }
    }
}

Enjoy!

*UPDATE* make sure you have Rx-experimental release. The GetAwaiter method is not in the stable release yet!

 
Follow

Get every new post delivered to your Inbox.