Performance Zone is brought to you in partnership with:

Jeremy Likness was named Silverlight MVP of the Year in 2010. Now Senior Consultant and Technical Project Manager for Wintellect, LLC, he has spent the past decade building highly scalable web-based commercial solutions using the Microsoft technology stack. He has fifteen years of experience developing enterprise applications in vertical markets including insurance, health/wellness, supply chain management, and mobility. He is the creator of the popular MVVM framework Jounce and an open source Silverlight Isolated Storage Database System called Sterling. Likness speaks and blogs frequently on Silverlight, MEF, Prism, Team Foundation Server, and related Microsoft technologies. Jeremy is a DZone MVB and is not an employee of DZone and has posted 64 posts at DZone. You can read more from them at their website. View Full User Profile

Asynchronous Commands in Windows Store Apps

03.13.2013
| 1333 views |
  • submit to reddit

The Model-View-View Model (MVVM) pattern is more popular than ever and is built into the Visual Studio templates for creating Windows Store apps. Developers familiar with Silverlight already encountered the platform shift to using asynchronous operations because it was impossible to generate a WCF client with synchronous methods. The Windows Runtime (WinRT) takes this further by dictating any operation that may potentially take longer than 50ms to complete should be asynchronous.

How does the MVVM pattern handle asynchronous operations, when the command interface ICommand only exposes synchronous methods?

namespace System.Windows.Input
{
     public interface ICommand
     {
         event EventHandler CanExecuteChanged;
         bool CanExecute(object parameter);
         void Execute(object parameter);
     }
}

Now consider a simple implementation of a command we’ll call an ActionCommand because it allows you to specify a delegate to perform and action when it is invoked. It also provides a predicate to condition the command and a public method to notify the command when the conditions for the predicate have changed.

namespace MyApp.Common
{
     using System;
     using System.Windows.Input;
     public class ActionCommand : ICommand
      {
         private readonly Action action;
         private readonly Func<bool> condition;

         public ActionCommand()
         {
             this.action = delegate { };
             this.condition = () => true;
         }
         public ActionCommand(Action action)
         {
             this.action = action;
             this.condition = () => true;
         }




         public ActionCommand(Action action, Func<bool> condition)
         {
             this.action = action;
             this.condition = condition;
         }
         

         public event EventHandler CanExecuteChanged = delegate { };
         public void RaiseExecuteChanged()
         {
             this.CanExecuteChanged(this, EventArgs.Empty);
         }
         public bool CanExecute(object parameter)
         {
             return this.condition();
         }
         public void Execute(object parameter)
         {
             this.action();
         }
     }
}

As you can see, there is no Task in the implementation of ICommand, nor any asynchronous code. As you are also aware, WinRT requires asynchronous code when you are performing various operations including a dialog. Here is an example of code that copies text and HTML to the clipboard and then shows a dialog to the end user they must confirm to acknowledge the copy was successful. The method is asynchronous.

private async Task Copy()
{
     var package = new DataPackage();
     package.SetText(this.DataManager.CurrentPage.Text);
     package.SetHtmlFormat(HtmlFormatHelper.CreateHtmlFormat
        (this.DataManager.CurrentPage.Html));
     Clipboard.SetContent(package);
     var dialog = new MessageDialog(
        "The web page was successfully copied to the clipboard.");
     await dialog.ShowAsync();
}

Now you have to wire it to the command implementation that is not asynchronous. How can you? Fortunately, the magic that is asynchronous code is able to combine forces with lambda expressions to enable you to handle asynchronous code “on the fly.” Here is the code to wire-up the command to call the Copy method asynchronously:

this.CopyCommand = new ActionCommand(
     async () => await this.Copy(),
     () => this.CopyEnabled);

That’s it. The action itself may be implemented as an asynchronous operation simply by invoking the async keyword and using the await operator. That’s how easy it is! While you should typically declare your interface consistently – for example, declaring them to return a Task when they should be implemented asynchronously – using this technique you can apply an asynchronous operation to the existing contract when needed. This means your commands can be asynchronous if and when needed, in full compliance with the WinRT guidelines.



Published at DZone with permission of Jeremy Likness, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)