Browse by Tags

All Tags » asynchronous   (RSS)

One enhancement that quietly slipped into the Silverlight 5 RC is the inclusion of Tasks. This is not the full-blown Task Parallel Library (TPL) to my knowledge (as it lacks the Parallel class and extensions) but it does provide Task, its related factories, and the functionality to chain and monitor tasks. The purpose of the library is to simplify asynchronous methods.

This post will show you an example of using the library. I'm not presenting this as a best practice, but only as a thought exercise to show you the use of the Task library in a visual way. The program computes the factorials of several numbers, but uses task continuation to ensure only one web service call is made at a time (thus simulating a sequential asynchronous workflow). You can modify the example to fire all threads simultaneously.

First, a simple service in the web project to compute the factorial:

[ServiceContract(Namespace = "http://jeremylikness.com/examples/")]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SimpleService
{
    [OperationContract]
    public long Factorial(int value)
    {
        long result = value;
        while (--value > 0)
        {
            result *= value;
        }
        return result;
    }       
}

Add the service reference to the Silverlight project. Next, create a simple class in the Silverlight project to hold the value and the result that implements property change notifications:

public class Factorial : INotifyPropertyChanged 
{
    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            _value = value;
            RaisePropertyChange("Value");
        }
    }

    private long _result;
    public long Result
    {
        get { return _result; }
        set
        {
            _result = value;
            RaisePropertyChange("Result");
        }
    }

    protected void RaisePropertyChange(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

The main page holds a button to fire off the calls and a list box to show the results:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="1" x:Name="FactorialList">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Value}"/>
                    <TextBlock Text="!="/>
                    <TextBlock Text="{Binding Result}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Click="_BtnFactorClick" x:Name="btnFactor" IsEnabled="False" 
            Content="Factor" HorizontalAlignment="Left"
            VerticalAlignment="Top" Margin="10"/>
</Grid>

In the code-behind for the main page, hold a list of the Factorial objects:

private readonly List<Factorial> _factorials;

Then populate it with the numbers 1 through 20 and bind it to the list box - at this point you can run the application and see the list of numbers to be factored:

public MainPage()
{
    InitializeComponent();

    _factorials = new List<Factorial>();
            
    for (var x = 0; x < 20; x++)
    {
        _factorials.Add(new Factorial {Value = x + 1});
    }

    FactorialList.ItemsSource = _factorials;
}

Add the code to create a channel for the service. Use this instead of the proxy client so you can take advantage of the asynchronous programming model (APM) and use the begin/end methods. The task library provides a way to conveniently convert an APM call to a task. This example simply builds the path to the service using the location of the XAP to ensure it always points to the correct URL:

var source = Application.Current.Host.Source;
var uriBuilder = new UriBuilder(source.Scheme, source.Host, source.Port, "/SimpleService.svc");

var channelFactory = new ChannelFactory<SimpleServiceChannel>(
    new BasicHttpBinding(), new EndpointAddress(uriBuilder.Uri));

var channel = channelFactory.CreateChannel();

At the top of the code-behind for the main page, add a list of tasks that return a long (the return type of the service):

private readonly List<Task<long>> _tasks; 

Create a method to return a task. The task factory launches the task immediately. In this example, you want one task to complete before firing the next. Therefore, the task factory call is wrapped in another task to kick it off. The task that is created directly will not launch until you explicitly invoke it. This method will return a task that is primed to return the result of the service call when it is invoked:

private Task<long> _CreateFactorialTask(int idx, SimpleService channel)
{
    return new Task<long>(() => Task<long>.Factory.FromAsync(
        channel.BeginFactorial,
        channel.EndFactorial,
        _factorials[idx].Value,
        null).Result);
}

If you want the threads to all fire simultaneously (to the extent the thread pool allows) simply remove the Task wrapper and return the result of the factory call directly.

Notice that the factory takes the form of "begin method" then "end method" followed by the parameters that are passed in. The last parameter is a state object that you don't need for this example. When the results return, they aren't guaranteed to return on the UI thread, so create a method to safely dispatch them when needed:

private void _SafeInvoke(Action action)
{
    if (Dispatcher.CheckAccess())
    {
        action();
    }
    else
    {
        Dispatcher.BeginInvoke(action);
    }
}

Now you can create the task list. Place this code after creating the factorial list. All the code does is create a list of task objects, and marks each one to continue by updating the result and then launching the next task in line. An additional method ensures the very last result is obtained, and then the button to kick off the process is enabled:

_tasks = new List<Task<long>>();

for (var count = 0; count < _factorials.Count; count++)
{
    _tasks.Add(_CreateFactorialTask(count, channel));

    if (count <= 0) continue;

    var localCount = count;
    _tasks[localCount - 1].ContinueWith(
        taskCompleted =>
            {
                _SafeInvoke(
                    () => 
                        _factorials[localCount - 1].Result = taskCompleted.Result);
                _tasks[localCount].Start();
                return _tasks[localCount];
            });
}

_tasks[_tasks.Count - 1].ContinueWith(
    taskCompleted =>
    _SafeInvoke(() =>
                _factorials[_factorials.Count - 1].Result = taskCompleted.Result));

btnFactor.IsEnabled = true;

If you know why the count is copied to the localCount variable, good job! If not, no worries. The tasks are being created using lambda expressions with anonymous methods, so the locally scoped variable is used to capture the value of the variable. This is referred to as a "closure" and you can learn more about it here.

Now you can run the application and the tasks will be queued up, but not running. The last step is to kick off the workflow. All that is required is to start the first task. Because the tasks were linked, each task will complete, update the results, then kick off a new task that will generate the next web service call. When you click the button, you should see the factorials updating in order.

private void _BtnFactorClick(object sender, RoutedEventArgs e)
{
    btnFactor.IsEnabled = false;
    _tasks[0].Start();
}

This example just scratched the surface of what is possible. You can convert event-based tasks using a task completion source, orchestrate groups of tasks to launch in parallel and wait for them to finish, and even nest tasks inside of other tasks. This is a very powerful and welcome addition to the Silverlight tool box!

Download the source here.

Jeremy Likness

The parallel tasks library was introduced with the .NET Framework 4.0 and is designed to simplify parallelism and concurrency. The API is very straightforward and usually involves passing in an Action to execute. Things get a little more interesting when you are dealing with asynchronous models such as events.

While the TPL has explicit wrappers for the asynchronous programming model (APM) that you can read about here: TPL APM Wrappers, there is no explicit way to manage events.

I usually hide the "muck" of subscribing and waiting for a completed action in events with a callback. For example, the following method generates a random number. I'm using a delay to simulate a service call and a thread task to make the call back asynchronous: you call into the method, then provide a delegate that is called once the information is available.

private static void _GenerateRandomNumber(Action<int> callback)
{
    var random = _random.Next(0, 2000) + 10;
    Console.WriteLine("Generated {0}", random);
    Task.Factory.StartNew(() =>
                                {
                                    Thread.Sleep(1000);
                                    callback(random);
                                }, TaskCreationOptions.None);
}

Now consider an algorithm that requires three separate calls to complete to provide the input values in order to compute a result. The calls are independent so they can be done in parallel. The TPL supports "parent" tasks that wait for their children to complete, and a first pass might look like this:

private static void _Incorrect()
{
            
    var start = DateTime.Now;

    int x = 0, y = 0, z = 0;

    Task.Factory.StartNew(
        () =>
            {
                Task.Factory.StartNew(() => _GenerateRandomNumber(result => x = result),
                                        TaskCreationOptions.AttachedToParent);
                Task.Factory.StartNew(() => _GenerateRandomNumber(result => y = result),
                                        TaskCreationOptions.AttachedToParent);
                Task.Factory.StartNew(() => _GenerateRandomNumber(result => z = result),
                                        TaskCreationOptions.AttachedToParent);
            }).ContinueWith(t =>
                                {
                                    var finish = DateTime.Now;
                                    Console.WriteLine("Bad Parallel: {0}+{1}+{2}={3} [{4}]",
                                        x, y, z,
                                        x+y+z,
                                        finish - start);
                                    _Parallel();                                            
                                });          
}

The code aggregates several tasks to the parent, the parent then waits for the children to finish and continues by computing the time span and showing the result. While the code executes extremely fast, the result is not what you want. Take a look:

Press ENTER to begin (and again to end)

Generated 593
Generated 1931
Generated 362
Bad Parallel: 0+0+0=0 [00:00:00.0190011]

You can see that three numbers were generated, but nothing was computed in the sum. The reason is that for the purposes of the TPL, the task ends when the code called ends. The TPL has no way to know that the callback was handed off to an asynchronous process (or event) and therefore considers the task complete once the generate call finishes executing. This returns and falls through and the computation is made before the callback fires and updates the values.

So how do you manage this and allow the tasks to execute in parallel but still make sure the values are retrieved?

For this purpose, the TPL provides a special class called TaskCompletionSource<T>. The task completion source is a point of synchronization that you can use to complete an asynchronous or event-based task and relay the result. The underlying task won't complete until an exception is thrown or the result is set.

To see how this is used, let's take the existing method and fix it using the completion sources:

private static void _Parallel()
{
    var taskCompletions = new[]
                                {
                                    new TaskCompletionSource<int>(), 
                                    new TaskCompletionSource<int>(),
                                    new TaskCompletionSource<int>()
                                };

    var tasks = new[] {taskCompletions[0].Task, taskCompletions[1].Task, taskCompletions[2].Task};

    var start = DateTime.Now;            

    Task.Factory.StartNew(() => _GenerateRandomNumber(result => taskCompletions[0].TrySetResult(result)));
    Task.Factory.StartNew(() => _GenerateRandomNumber(result => taskCompletions[1].TrySetResult(result)));
    Task.Factory.StartNew(() => _GenerateRandomNumber(result => taskCompletions[2].TrySetResult(result)));

    Task.WaitAll(tasks);

    var finish = DateTime.Now;
    Console.WriteLine("Parallel: {0}+{1}+{2}={3} [{4}]", 
        taskCompletions[0].Task.Result,
        taskCompletions[1].Task.Result,
        taskCompletions[2].Task.Result,
        taskCompletions[0].Task.Result + taskCompletions[1].Task.Result + taskCompletions[2].Task.Result, 
        finish - start);            
}

First, I create an array of the task completions. This makes for an easy reference to coordinate the results. Next, I create an array of the underlying tasks. This provides a collection to pass to Task.WaitAll() to synchronize all return values before computing the result. Instead of using variables, the tasks now use the TaskCompletionSource to set the results after the simulated callback. The tasks won't complete until the result is set, so all values are returned before the final computation is made. Here are the results:

Generated 279
Generated 618
Generated 1013
Parallel: 618+279+1013=1910 [00:00:01.9981143]

You can see that all generated numbers are accounted for and properly added. You can also see that the tasks ran in parallel because it completed in under 2 seconds when each call had a 1 second delay.

The entire console application can simply be cut and pasted from the following code — there are other ways to chain the tasks and make the completions fall under a parent but this should help you get your arms wrapped around dealing with tasks that don't complete when the methods return, but require a synchronized completion context.

class Program
{
    private static readonly Random _random = new Random();

    static void Main(string[] args)
    {
        Console.WriteLine("Press ENTER to begin (and again to end)");
        Console.ReadLine();

        _Incorrect();
            
        Console.ReadLine();                                                            
    }

    private static void _Incorrect()
    {
            
        var start = DateTime.Now;

        int x = 0, y = 0, z = 0;

        Task.Factory.StartNew(
            () =>
                {
                    Task.Factory.StartNew(() => _GenerateRandomNumber(result => x = result),
                                            TaskCreationOptions.AttachedToParent);
                    Task.Factory.StartNew(() => _GenerateRandomNumber(result => y = result),
                                            TaskCreationOptions.AttachedToParent);
                    Task.Factory.StartNew(() => _GenerateRandomNumber(result => z = result),
                                            TaskCreationOptions.AttachedToParent);
                }).ContinueWith(t =>
                                    {
                                        var finish = DateTime.Now;
                                        Console.WriteLine("Bad Parallel: {0}+{1}+{2}={3} [{4}]",
                                            x, y, z,
                                            x+y+z,
                                            finish - start);
                                        _Parallel();                                            
                                    });          
    }

    private static void _Parallel()
    {
        var taskCompletions = new[]
                                    {
                                        new TaskCompletionSource<int>(), 
                                        new TaskCompletionSource<int>(),
                                        new TaskCompletionSource<int>()
                                    };

        var tasks = new[] {taskCompletions[0].Task, taskCompletions[1].Task, taskCompletions[2].Task};

        var start = DateTime.Now;            

        Task.Factory.StartNew(() => _GenerateRandomNumber(result => taskCompletions[0].TrySetResult(result)));
        Task.Factory.StartNew(() => _GenerateRandomNumber(result => taskCompletions[1].TrySetResult(result)));
        Task.Factory.StartNew(() => _GenerateRandomNumber(result => taskCompletions[2].TrySetResult(result)));

        Task.WaitAll(tasks);

        var finish = DateTime.Now;
        Console.WriteLine("Parallel: {0}+{1}+{2}={3} [{4}]", 
            taskCompletions[0].Task.Result,
            taskCompletions[1].Task.Result,
            taskCompletions[2].Task.Result,
            taskCompletions[0].Task.Result + taskCompletions[1].Task.Result + taskCompletions[2].Task.Result, 
            finish - start);            
    }

    private static void _GenerateRandomNumber(Action<int> callback)
    {
        var random = _random.Next(0, 2000) + 10;
        Console.WriteLine("Generated {0}", random);
        Task.Factory.StartNew(() =>
                                    {
                                        Thread.Sleep(1000);
                                        callback(random);
                                    }, TaskCreationOptions.None);
    }
}

Jeremy Likness

I've blogged several times about how I like to handle services in Silverlight. For two key posts, take a look at:

In this post we'll explore the difference between using the actual contract for a WCF service in Silverlight versus using the generated client. The difference is subtle but important, and involves not only the event-based model and the Asynchronous Programming Model (APM) but also some nuances with threads.

There is no code project for this because the nuance is in the way you call the service, not the example itself, but there should be enough code in this post for you to recreate the example if you want to test it yourself.

Here's the rub: let's create a simple service that adds two integers and returns the result. The contract is simply:

[ServiceContract(Namespace = "http://jeremylikness.com/silverlight/")]
public interface IAddService
{
    [OperationContract]
    int Add(int x, int y);
}

Now we can implement it - just add the numbers and return the value:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AddService : IAddService
{        
    public int Add(int x, int y)
    {
        return x + y;
    }        
}

So that's easy enough (and we've jumped through our first Silverlight hoop by flagging the service with the compatibility attribute). Now we'll fire up a new Silverlight application and reference the service. I'm not doing anything fancy, just discovering the service within the project and letting Silverlight generate the code. Now things get a little more interesting.

Let's add two list boxes that will race each other for results. They are bound to a simple list of integers:

<UserControl.Resources>
    <DataTemplate x:Key="ListTemplate">
        <TextBlock Text="{Binding}"/>
    </DataTemplate>               
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Events"/>
    <TextBlock Text="APM" Grid.Column="1"/>
    <ListBox x:Name="Events" ItemsSource="{Binding Series1}" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top"
                ItemTemplate="{StaticResource ListTemplate}"/>        
    <ListBox x:Name="APM" ItemsSource="{Binding Series2}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Top"
                ItemTemplate="{StaticResource ListTemplate}"/>          
</Grid>

As you might have already guessed, we're going to use the event model and the APM model. Let's wire some code.

First, two collections to hold the results. I also bind the data context to itself so I can bind to the series in the code-behind.

private const int MAX = 999999999;

public ObservableCollection<int> Series1 { get; private set; }
public ObservableCollection<int> Series2 { get; private set; }      

public MainPage()
{
    InitializeComponent();

    Loaded += (o, e) => LayoutRoot.DataContext = this;

    Series1 = new ObservableCollection<int>();
    Series2 = new ObservableCollection<int>();

    if (DesignerProperties.IsInDesignTool) return;

    _Series1(); 
    _Series2();
}

The Main Event

Now let's implement a Fibonacci sequence using the event-based model:

private void _Series1()
{
    var y = 1;
    var x = 1;

    var client = new AddServiceClient();

    Series1.Add(1);
    client.AddCompleted += (o, e) =>
                                    {
                                        x = e.Result;

                                        Series1.Add(x);            

                                        var z = y;
                                        y = x;

                                        if (x 

Notice how we recursively call the service. What is also important to note, however, is that there is no special use of the dispatcher. I know for a fact this will come back to me on the UI thread. Why? Because I registered the event on the UI thread, and that registration is where the return call will go. I can prove it because despite the fact the series is databound to the UI, it populates without any issue.

Switching to the Asynchronous Programming Model

Now, let's wire the same service using the Asynchronous Programming Model (APM). I'm going to kick it off the same way and in the same context as the event-based version. Notice that because Silverlight creates the client proxy using the event-based model, I actually have to cast the client to the interface in order to take advantage of the APM model.

The APM call adds two methods. One is an AsyncCallback delegate that will be called when the service is done fetching results, and the other is an optional object to store state (this is passed to the callback so you can reference data from the original call).

private void _Series2()
{            
    // add the first item
    Series2.Add(1);

    var client = (IAddService) new AddServiceClient();

    AsyncCallback end = null;
    end = ar =>
                            {
                                var state = ar.AsyncState as Tuple<IAddService, int>;
                                if (state == null) return;
                                var x = state.Item1.EndAdd(ar);
                                var y = state.Item2;

                                Deployment.Current.Dispatcher.BeginInvoke(() => Series2.Add(x));

                                if (x < MAX)
                                {
                                    state.Item1.BeginAdd(x, y, end, Tuple.Create(state.Item1, x));
                                }
                            };

    client.BeginAdd(1, 1, end, Tuple.Create(client,1));            
}          

There's a bit going on there - I preserve the original client along with the current value in the state by casting them both into a tuple, and unroll them in the callback. The call is recursive until the max is reached, just like the event model, and using an anonymous method. However, there is a subtle difference between the AddAsync method we called earlier and the BeginAdd method here.

The difference? Our "end" callback is not invoked on the UI thread! The APM model lets the result come back on a different thread. If you take out the dispatcher call I use to populate the series and add the value directly, you'll get a cross-thread exception.

So what does this mean?

Most of the time, quite frankly, not much. In my tests, the bulk of the time for the process to run is taken in the service call going over the wire and coming back, and there is little noticeable difference between staying on the UI thread or not (even on a local machine).

However, if you are receiving a result and doing heavy processing before displaying the data, you don't want to return on the UI thread. It's wasteful and can causing blocking, the exact thing the asynchronous pattern is supposed to avoid! While you could send your work to a background worker, the easiest solution is to use the APM model. You'll return on a background thread where you can do all of your heavy lifting and simply dispatch the result when you're ready.

Bottom line: when using services in Silverlight, know where your results land!

Jeremy Likness

I've been doing quite a bit with Reactive Extensions (Rx) for Silverlight lately. One idea that I keep exploring is the concept of creative intuitive sequential workflows for asynchronous operations. You can read about my explorations using Wintellect's own Power Threading Library in this post along with a simple solution using an interface and enumerators in part 2 of that series. I'm tackling the problem from a different angle.

First, my disclaimers: this is more of an exploratory, "Here's what can be done" post. Please don't take this as best practice or guidance, but more of another way of looking at the solution as well as an opportunity to dive deeper into Reactive Extensions. Also understand I am by no means an expert with Rx so I welcome feedback related to this experiment.

The concept is straightforward: there are often times we want an asynchronous set of operations to perform sequentially. Perhaps you must load a list from a service, then load the selected item, then trigger an animation. This can be done either by chaining the completed events or nesting lambda expressions, but is there a cleaner way?

To me, a cleaner solution would make it easy to see what happens sequentially, and also easy to fire the sequence. If it becomes too complex to force the sequential workflow, it buys us nothing from the traditional methods of wiring into completed events or nesting lambda expressions.

So, I started with the idea of having a helper object that I could feed operations to in sequence, then fire it off. What would that look like?

First, I made an interface to keep track of operations as they run and complete. This is by no means a perfect design but for now it's a sort of "recrusive container" for work done. The interface looks like this:

public interface ISequentialResult 
{
    List<ISequentialResult> Results { get; set; }
    object Value { get; set; }        
}

The result is simple: it aggregates all previous results, and contains a pointer to whatever is processing the current action in the sequence. Simple enough. Now on to a base class:

public abstract class BaseResult<T> : ISequentialResult 
{
    protected IObserver<ISequentialResult> Observer { get; set; }

    protected BaseResult(IObserver<ISequentialResult> observer)
    {
        Results = new List<ISequentialResult>();
        Observer = observer;
    }

    public List<ISequentialResult> Results { get; set;}

    public object Value { get; set; }       

    public T TypedValue
    {
        get { return (T) Value; }
        set { Value = value; }
    }
}

The base class does a little more for us. First, it introduces the concept of an IObserver. The observer is simply a class that receives notifications, and the type is the type of the notification. In this case, we allow for a derived type that will create the observer as well as take our "object" value and type it to a specific value. You'll see how the observer works with our sequences in a bit.

Next, I created three implementations. One is just a default that does nothing, and the other two handle Click events and Storyboard interactions. Let's take a look at the handler for storyboards:

public class StoryboardResult : BaseResult<Storyboard>  
{
    public StoryboardResult(IObserver<ISequentialResult> observer, Storyboard sb) : base(observer)
    {
        TypedValue = sb;
        sb.Completed += SbCompleted;
        sb.Begin();
    }

    void SbCompleted(object sender, EventArgs e)
    {
        TypedValue.Completed -= SbCompleted;
        Observer.OnNext(this);
        Observer.OnCompleted();
    }       
}

You'll notice a few interesting things. We take in the story board, wire into its Completed event, then fire it off (we could have changed the interface to have an Execute method to give this more flexibility). The story board completion is the important piece to consider. First, the event is unhooked. Then, we pass the result to the observer. The observer is waiting for ISequentialResult notifications. We provide it with one, but only after the story board is completed. We also tell the observer "we're done" (an observer can listen for multiple push notifications, so we could have created a handler that never completed, or one that aggregated multiple storyboards and only completed when all story boards were done).

With that in mind, take a look at the Click handler:

public class ClickResult : BaseResult<ButtonBase>
{
    public ClickResult(IObserver<ISequentialResult> observer, ButtonBase button) : base(observer)
    {
        TypedValue = button;
        button.Click += ButtonClick;
    }

    void ButtonClick(object sender, System.Windows.RoutedEventArgs e)
    {
        TypedValue.Click -= ButtonClick;
        Observer.OnNext(this);
        Observer.OnCompleted();                 
    }
}

This is very similar to the storyboard. There is nothing to "kick off" but instead this result simply registers itself whenever the target is clicked. Why would we do that? I'll get to the example in a minute.

The most interesting part of workflow is the sequencer itself. This is the class that will manage the asychronous events and coordinate them. The key is that while they run sequentially, they also run asynchronously so there is no blocking.

Here is the sequencer class:

public class Sequencer : IDisposable 
{
    private IDisposable _sequence;
    private ISequentialResult _result;

    private readonly List<Func<IObserver<ISequentialResult>,ISequentialResult,ISequentialResult>> _sequences
        = new List<Func<IObserver<ISequentialResult>, ISequentialResult,ISequentialResult>>();

    public void AddSequence(Func<IObserver<ISequentialResult>, ISequentialResult,ISequentialResult> sequence)
    {
        _sequences.Add(sequence);
    }
        
    public void Run(Action<Exception> exception, Action<ISequentialResult> completed)
    {
        _sequence = Observable.Iterate(_Sequencer)
            .Subscribe(
                next => { },
                exception,
                ()=>completed(_result));
    }

    private IEnumerable<IObservable<Object>> _Sequencer()
    {
        var x = 0;

        _result = new DefaultResult(null) {Value = this};

        while (x (
                observer =>
                    {
                        var newResult = sequence(observer, _result);
                        newResult.Results.Add(_result);
                        newResult.Results.AddRange(_result.Results);
                        _result = newResult;
                        return () => { };
                    }
                ).Start();

            yield return step;                

            x++;
        }

        _result.Results.Add(_result);
    }

    public void Dispose()
    {
        _sequence.Dispose();
    }
}

There's a lot going on here, so let's break it down.

First, you'll notice two references: one to a disposable object, and one to a result. More on those in a bit.

The list may seem confusing at first, but it's only because of all of the type specifiers. Each "step" is represented by a function. The sequence will call the function with an observer and the previous result, and expect to get a new result back. Think of it as "here's who is watching, and what happened the last time ... now give me what you have."

A method is provided to add these steps to the sequence.

The run method is interesting. This is where we set up our disposable reference because we're creating a long-running observer that we want to dispose of when the sequence itself is disposed. The iterate function takes a list of observable sequences and observes them sequentially. We provide an enumerator that feeds the observable sequences, and for each sequence in the "outer loop" (the main algorithm that drives the sequential work flow) we simply drive through the collection. If an exception is encountered, we'll call back with the exception. When completed, we call back with the final result.

To better understand what's going on, take a look at the enumerator. For each iteration, we create a new observable stream. We call the function I mentioned earlier and pass the observer in. When we receive the result, we stack it recursively and store it, then iterate to the next in line. The yield statement ensures the sequential operation completes (when we call the OnCompleted in our result) before the next step begins.

That's the complicated part: setting up the core framework. Now comes the easy part: plugging into it.

In the XAML I placed a large red rectangle. There are three storyboards tied to the rectangle. One changes the colors, one shrinks it, and one twists it using the plane projection. There are also three buttons. One button kicks off the story boards. One button kicks off a sequential workflow that will run the story boards in order. The final button resets the story boards by calling Stop on them.

Let's have some fun. First, kicking off the story boards is simple enough:

private void Button_Click(object sender, RoutedEventArgs e)
{
    StoryTwist.Begin();
    StoryShrink.Begin();
    StoryColor.Begin();
}

The reset button is also easy:

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    StoryTwist.Stop();
    StoryShrink.Stop();
    StoryColor.Stop();
}

Now for the sequential storyboards. This is where things should get easier for us. Instead of having to wire in several completed events or nesting lambdas, let's see what it looks like to run them in order using our sequencer:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    _sequence = new Sequencer();
    _sequence.AddSequence((o, r) => new StoryboardResult(o, StoryColor));
    _sequence.AddSequence((o, r) => new StoryboardResult(o, StoryShrink));
    _sequence.AddSequence((o, r) => new StoryboardResult(o, StoryTwist));
    _sequence.Run(ex => MessageBox.Show(ex.Message),
                    result =>
                        {
                            foreach (var storyboard in
                                result.Results.Select(sequence => sequence.Value).OfType<Storyboard>())
                            {
                                storyboard.Stop();
                            }
                            _sequence.Dispose();
                            _sequence = null;
                        });
}       

So what's going on? If we have a previous sequence running, we dispose it so we can start fresh. Then, we simply add each story board in the order we want it to fire (the observer is provided to us by the sequencer). Finally, we run it. If there is an error, show it. When the sequence is done, we iterate the results and find any result that was a story board and call the "stop" method. This means after the sequence completes, it will automatically restore the rectangle to its original state.

Finally, to show just how powerful it is to drive sequential workflows without blocking, I added one more method:

private void _WaitForThreeClicks()
{
    _buttonSequence = new Sequencer();
    _buttonSequence.AddSequence((o, r) => new ClickResult(o, ResetButton));
    _buttonSequence.AddSequence((o, r) => new ClickResult(o, ResetButton));
    _buttonSequence.AddSequence((o, r) => new ClickResult(o, ResetButton));
    _buttonSequence.Run(ex=>MessageBox.Show(ex.Message),
        result=>
            {
                MessageBox.Show("You clicked the Reset button 3 times!");
                _buttonSequence.Dispose();
                _WaitForThreeClicks();
            });
}

This is a fun method. It literally creates three sequences, all "waiting" for the reset button to be clicked. After the sequence completes, we show a message indicating that 3 clicks happened, then restart the sequence recursively. I'll call it the first time just after IinitializeComponent:

public MainPage()
{
    InitializeComponent();  
    _WaitForThreeClicks();
}      

There you have it! When you run the code, you'll get this:


Notice that you can keep clicking the sequence to start it over: there is no blocking. And whatever order you decide to click on other buttons, the reset button always faithfully shows a "3 click" message on the third click.

You can download the full source code for this solution here.
Jeremy Likness

I received quite a bit of feedback related to my sequential asynchronous workflows post. Most people asked if I could simplify the example even more and/or show the inner workings of the coroutine engine itself. Because the source for the library I demonstrated in the last post is not available, I've put together a very simple solution to help you better understand and take advantage of coroutines.

First, the fine print. This framework is simply to help understand the concept and provide a starting point for building out coroutines yourself. I know some companies simple don't allow third-party code and it always helps to learn a framework by starting at the ground floor. Some things you won't find here that would belong in production code include thread-awareness (background or UI thread?), timeouts (i.e. if I call out and it never returns, does my workflow die?) and exception management. All very important but reasons why this framework is educational and not a "production-ready" implementation.

Download the source for this post

Remember the original interface we defined for illustration purposes, the ICoroutine interface? Here it is:

public interface ICoroutine
{
    void Yield();
    Action Yielded { get; set; }
}

Now, to drive a workflow, you simply need an engine. Let's build a quick and dirty engine to drive what we want. Last post I showed how to use an existing framework. This time we'll do it a little differently. Instead of queuing asynchronous calls using the asynchronous process model, we'll drive the process with the coroutine interface itself. This comes with some caveats. What I'm going to show you will work, but a production solution will have to take it a step further and deal with things like execution threads (background vs. UI) etc (this is all handled as part of the AsyncEnumerator class I showed you before).

So, here is our "bare bones" coroutine manager, and again, this is closer to Rob Eisenberg's implementation in his MIX session on building your own MVVM framework than the version I showed you last time, but I've taken it and dumbed it down as much as possible to make it easy to use and understand.

public class CoroutineManager
{
    private readonly IEnumerator<ICoroutine> _enumerator;

    public CoroutineManager(IEnumerable<ICoroutine> workflow)
    {
        _enumerator = workflow.GetEnumerator();
    }
    
    private void Yielded()
    {            
        if(!_enumerator.MoveNext())
            return;

        var next = _enumerator.Current;
        next.Yielded = Yielded; 
        next.Yield();
    }
    
    public static void Begin(object workflow)
    {
        if (workflow is ICoroutine)
        {
            workflow = new[] {workflow as ICoroutine};
        }
        
        if (workflow is IEnumerable<ICoroutine>)
        {
            new CoroutineManager(workflow as IEnumerable<ICoroutine>).Yielded();
        }            
    }     
}

Not much to it, is there? The class has an entry point that can take a single coroutine or group, instantiate the class, then kick off the workflow. The workflow simply takes the next coroutine from the stack, wires in the yielded event to call back into the coroutine manager, and then executes it. That's it!

So how does it look? Let's make two helper classes: one that is generic and can handle any type of action, and another that is specific to our random number service.

Here's what the generic action coroutine looks like:

public class ActionCoroutine : ICoroutine 
{
    private readonly bool _immediate;

    public Action Execute { get; set; }

    public ActionCoroutine()
    {
        
    }

    public ActionCoroutine(bool immediate)
    {
        _immediate = immediate;
    }

    public ActionCoroutine(Action action)
    {
        _immediate = false;
        Execute = action;
    }

    public ActionCoroutine(Action action, bool immediate)
    {
        _immediate = immediate;
        Execute = action;
    }

    public void Yield()
    {
        Execute();
        if (_immediate)
        {
            Yielded();
        }
    }

    public Action Yielded { get; set; }  
}

Again, not much to it. I can either pass an action to trigger immediately, or pass an action and set immediate to false. If I set immediate to false, then I need to wire in something to call the Yielded method (remember, our coroutine manager wires this up for us to re-enter the iterator state machine). I'll show you usage in a second. Finally, here is my random number service helper:

public class RandomResultCoroutine : ICoroutine
{
    private readonly RandomNumberService _service;

    public RandomResultCoroutine(RandomNumberService service)
    {
        _service = service;
    }

    public int Max { get; set; }

    public int Result { get; set; }

    public void Yield()
    {
        _service.GetRandomNumber(Max,
                                 result =>
                                     {
                                         Result = result;
                                         Yielded();
                                     });
    }

    public Action Yielded { get; set; }
}

Notice how this service "wires itself." It has a max setting, calls the random number service, and tells the random number service to call back into a lambda expression. The expression sets the return result, then fires the Yielded message to re-enter the state machine flow.

This is an example where we can make it work, but a more robust solution will have to handle the exceptions. For example, what if the service never calls my action? Then I'm in a bad state because the Yielded will never get executed. That's why having timeouts and other checks and balances are important for a production-ready solution.

OK, we've set up our simple helpers and coroutine manager, let's see it in action. I'm just going to do everything in the code-behind for the main page to keep it simple. I'll set up three workflows. Two will generate shapes (circles and squares) and then feed the shapes to the third workflow which animates colors. This means we'll actually have dozens of workflows running simultaneously, but they will still fire sequentially within the workflow.

Take a look at our color workflow (it has as many iterations as seconds are in a day, just to keep it going for you to watch):

private IEnumerable<ICoroutine> ColorWorkflow(Shape element)
{
    for (int x = 0; x 
                                    {
                                        element.Fill = new SolidColorBrush(color);
                                        ((Storyboard) o).Stop();
                                        storyboardAction.Yielded();
                                    };

        yield return storyboardAction; 
    }

    yield break; 
}

Notice how straightforward it is. With our direct random number service helper, we can keep yield returning results. We will only go past the yield statement when the service call actually returns, and we can inspect the result because of the field we added to the helper, which is only set when the result is received and before the state machine is re-entered by calling yielded.

What's nice about implementing the ICoroutine interface is that all you have to do to repeat the call and get a new result is simply yield the same helper class. The implementation ensures that the manager will call into it, block until a result is received, then continue execution with the new value available.

For the storyboard, we use the generic action coroutine. The begin action is set to kick off the storyboard and when it ends we set the new color and stop the storyboard. In this case I also wire in a call to yielded and set the "immediate" flag to false because we're depending on the story board completion to continue the workflow.

The square and circle workflows are exactly the same, so I'll just show the square one here (probably means they could be refactored to something simpler, too, but it works for this demonstration).

private IEnumerable SquareWorkflow()
{            
    var randomAction = new RandomResultCoroutine(_service) {Max = 20};

    randomAction.Yield();
    yield return randomAction;

    int iterations = randomAction.Result + 5;

    for (int x = 0; x  LayoutRoot.Children.Add(rectangle), false);                                   
        rectangle.Loaded += (o, e) => loadedSquare.Yielded();

        yield return loadedSquare;

        CoroutineManager.Begin(ColorWorkflow(rectangle));
    }

    yield break;
}

This time we get a random number of squares and begin setting them up. We have a random size for the squares. Note we use the generic action coroutine to fire adding the square and loading it, and only when it is loaded do we kick off the color workflow to begin animating the colors on the square. This same workflow is repeated for circles.

You see how easy it is to kick off the routine? In fact, to kick off the main workflows, we simply do this:

public MainPage()
{
    InitializeComponent();
    Loaded += MainPage_Loaded;
}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    CoroutineManager.Begin(SquareWorkflow());
    CoroutineManager.Begin(CircleWorkflow());
}

With those kicked off, even though we have two coroutines, you'll see they run asynchronously. While the circles and squares are sequentially added and animated (as opposed to popping in immediately as would happen if they were asynchronous within the workflow), they do so in parallel with each other (and once loaded, all of the color workflows continue to animate the individual elements but don't kick off a new color until the old storyboard is complete).

Here it is to play with. Due to a bug (can you find it?) the storyboard animation runs and completes but we only see the color change when it's done. That's OK because you can pick any shape on the surface and count 2 seconds and you'll notice the color changes every 2 seconds ... for every shape, proof that we have simultaneous sequential workflows all running asynchronously with each other. We also may see some CPU and memory issues over time because I'm not unhooking events.

Hopefully this helped simplify it a bit for those of you who were having trouble with the last post or wanted to see the innards of a framework so you can begin to build your own infrastructure.

Download the source for this post

Jeremy Likness

I noticed on the forums there are a lot of users not comfortable with asynchronous programming who struggle a bit in Silverlight with getting their arms around the concept of a dialog box. In other environments, you can simply shoot out a dialog, wait for the response, and continue. In Silverlight, of course, the action is asynchronous. I would argue it should be this way most of the time.

The problem is that many people tend to take the approach of trying to force the process into a synchronous one, instead of changing the way they think and approach the application. There is a reason why processes are asynchronous in Silverlight. There is one main UI thread, and a blocking process would block the entire thread and effectively freeze the Silverlight application. Having the process asynchronous allows you to continue to render graphics elements, perform actions in the background, even display a soothing animation while you await the user's response.

I spoke to a more highly decoupled approach in a post awhile ago that was more an experiment with the event aggregator: Decoupled Child Window Dialogs with Silverlight and PRISM. Here, I want to show the more straightforward approach.

The first step is to choose what the dialog will be displayed with. In Silverlight, the ChildWindow makes perfect sense because it is a modal dialog that appears, waits for the user response, and then saves the response. We'll create a new child window and call it Dialog.xaml. It looks like this:

<controls:ChildWindow x:Class="SimpleDialog.Dialog"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
           Width="400" Height="300" 
           Title="{Binding Title}">
    <Grid x:Name="LayoutRoot" Margin="2">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBlock TextWrapping="Wrap" Grid.Row="0" Text="{Binding Message}"/>
        <Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
        <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
    </Grid>
</controls:ChildWindow>

You'll notice I made very few changes from the provided template. The key here is that I changed the title to bind with the Title property, and added a text block to display a message from the Message property.

Because this is a simple dialog box, I really feel a view model is overkill. Some purists will insist on this but I argue the functionality is simple enough that we don't need the extra overhead. We'll be using an interface to the solution down the road that we can easily unit test, and this makes the dialog function (which lives entirely in the UI) a self-contained implementation.

Next, I made a few changes to the code behind:

public partial class Dialog : ChildWindow
{
    public Action<bool> CloseAction { get; set; }

    public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(
        "Message",
        typeof(string),
        typeof(Dialog),
        null);


    public string Message
    {
        get { return GetValue(MessageProperty).ToString(); }
        set { SetValue(MessageProperty, value); }
    }

    public Dialog()
    {
        InitializeComponent();
        DataContext = this;
    }        

    public Dialog(bool allowCancel)
        : this()
    {
        CancelButton.Visibility = allowCancel ? Visibility.Visible : Visibility.Collapsed;
    }

    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;            
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;           
    }
}

Again, not too many changes here. I added the Message property as a dependency property, and in the constructor I set the data context to itself. This allows me to bind to the title and message. This allows us to simply set the message on the dialog and have it appear. I also added an action for it to retain when closed. This will store a callback so that it can notify the host of the user's final actions. Finally, there is a method that conditions whether or not there is the option for a cancel button. For alerts, we'll simply show an OK button. For confirmations, we'll show the Cancel button as well.

Next is a simple interface to the dialog. Nothing in our application should know or care how the dialog is displayed. There is simply a mechanism to display the dialog and possibly acquire a response. The interface looks like this:

public interface IDialogService
{
    void ShowDialog(string title, string message, bool allowCancel, Action<bool> response);
}

In our simple demonstration, I'm allowing for a title, a message, whether or not you want to show the cancel button for confirmations, and then an action to call with the response. With this simple interface we have all we need to wire in unit tests for services and controls that rely on the dialog. You can create your own mock object that implements the IDialogService interface and returns whatever response you want to stage for the unit test.

In the production application, we'll need to show a real dialog. Here is the class that handles it:

public class DialogService : IDialogService
{
    #region IDialogService Members

    public void ShowDialog(string title, string message, bool allowCancel, Action<bool> response)
    {
        var dialog = new Dialog(allowCancel) {Title = title, Message = message, CloseAction = response};
        dialog.Closed += DialogClosed;
        dialog.Show();
    }

    static void DialogClosed(object sender, EventArgs e)
    {
        var dialog = sender as Dialog;
        if (dialog != null)
        {
            dialog.Closed -= DialogClosed; 
            dialog.CloseAction(dialog.DialogResult == true);
        }
    }

    #endregion
}

This is fairly straightforward. When called, we'll create an instance of the dialog and set the various properties, including the callback. We wire into the closed event. Whether the user responds by clicking a button or closing the dialog, this event is fired.

There is a reason why we are using the snippet DialogResult == true. The result is null-able, so we cannot simply refer to the value itself and make a true/false decision (null, by definition, is unknown). So only if the user explicitly provides a true response by clicking the OK button will the expression evaluate to true. Otherwise, we assume false and call back with the response.

There is also a very important step here that is important to recognize. Many beginners fail to catch this subtle step and end up with memory leaks. When the closed event fires, the dialog box effectively closes. Typically, there would be no more references to it (it is no longer in the visual tree) and it can be cleaned up by garbage collection. However, there is a fatal mistake you can make that will result in the dialog box never going away.

That mistake has to do with how events work. When we register the closed event, the thought process is often that the dialog box has an event, and therefore knows to call back to the dialog service. This is flawed, however. A reference exists from the dialog service to the dialog box. The dialog service effectively "listens" for the event, and when it is raised, will respond. We must unregister the event like this:

dialog.Closed -= DialogClosed;

Otherwise, the reference remains and garbage collection will never claim the dialog box resource. In a long running application, this could prove to be a serious flaw. This line is not included in the code sample download. I encourage you to run with windbg or even step through debug in Visual Studio and watch the object graphs and reference counts as you fire multiple dialogs. Then, add the line of code above and re-run it to see the difference when you appropriately unregister the event.

To demonstrate the use of the service, I put together a quick little page with a few buttons and a text block:

<UserControl x:Class="SimpleDialog.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">
        <StackPanel Orientation="Vertical">
            <Button x:Name="ToggleEnabled" 
                    HorizontalAlignment="Center"
                    Margin="5" Width="Auto" Content="Disable Dialog Button" Click="ToggleEnabled_Click"/>
            <Button x:Name="DialogButton" 
                    HorizontalAlignment="Center"
                    Margin="5" Width="Auto" Content="DialogButton" Click="DialogButton_Click"/>
            <TextBlock x:Name="TextDialog" 
                       HorizontalAlignment="Center"
                       Margin="5" Width="Auto" Text="Result Will Show Here"/>
        </StackPanel>
    </Grid>
</UserControl>

The first button is a toggle to enable or disable the second button. It shows how to receive a response and act based on the user input. If the user confirms, the button is toggled to enabled or disabled. If the user cancels or closes the dialog, the state of the button remains the same. The second button raises a dialog, and simply shows the result. Because it is an alert dialog, we know a false response indicates the user closed the window instead of clicking OK.

Here is the code behind:

public partial class MainPage : UserControl
{
    private bool _toggleState = true;
    private readonly IDialogService _dialog = new DialogService();

    public MainPage()
    {
        InitializeComponent();
    }

    private void ToggleEnabled_Click(object sender, RoutedEventArgs e)
    {
        _dialog.ShowDialog(
            _toggleState ? "Disable Button" : "Enable Button",
            _toggleState
                ? "Are you sure you want to disable the dialog button?"
                : "Are you sure you want to enable the dialog button?",
            true,
            r =>
                {
                    if (r)
                    {
                        _toggleState = !_toggleState;
                        DialogButton.IsEnabled = _toggleState;
                        ToggleEnabled.Content = _toggleState ? "Disable Dialog Button" : "Enable Dialog Button";
                    }
                });
    }

    private void DialogButton_Click(object sender, RoutedEventArgs e)
    {
        _dialog.ShowDialog(
            "Confirm This",
            "You have to either close the window or click OK to confirm this.",
            false,
            r => { TextDialog.Text = r ? "You clicked OK." : "You closed the dialog."; });
    }
}

Notice that in the click events, we call to the dialog service and pass it anonymous methods for the return types. We could point to real methods on the class as well. The important part is to change your thought process from synchronous step one => wait => step two to asynchronous step one => delegate to step two, then step two is called when ready.

In a production application, instead of creating an instance of the dialog box, we would either register it with a container:

Container.RegisterInstance<IDialogService>(Container.Resolve<DialogService>());

And inject it in a constructor, or use something like MEF and import the dialog service:

[Import]
public IDialogService Dialog { get; set; }

We would simply flag the implementation as the export or use the InheritedExport attribute on the interface itself.

Click here to download the source code for this example.

Jeremy Likness

This post explores a way to encapsulate web service calls from Silverlight in a way that is easy to use and understand.

As anyone who works with Silverlight knows, Silverlight forces web service calls to be asynchronous. There is a good reason for this, which I won't get into with this post. What I would like to do is demonstrate an approach that advocates a clean separation of the internals of the service from the application that is consuming it.

First, I am assuming you understand web services and WCF. I assume you've called services from Silverlight, and are aware of the nuances of configuring the endpoint, etc. I am also going to assume you are familiar with some frameworks such as Prism, MEF, Caliburn, etc that advocate clean separation of concerns and modular design.

Let's assume I have a service on my web page that is a calculator (oh, where did I get that idea?) It looks something like this:


[ServiceContract(Namespace = "http://www.wintellect.com/sample")]    
public interface ICalculatorService
{
    [OperationContract]
    long Multiply(int x, int y);
}

Simple, correct? The first thing I'm going to do is to create a similar interface on my Silverlight client. This interface will hide the details of how the service is connected and wired. I also want to make it easier to deal with the asynchronous nature of the calls. I've seen some pretty exotic implementations to try to make an asynchronous call look synchronous, and don't quite understand why we'd want to do it. Instead, let's just define a contract like this somewhere in the Silverlight application that is "seen" globally:


public interface ICalculator 
{
   void Multiply(int x, int y, Action<long> result); 
}

As you can see, it's a simple void method ... in fact, all methods we use to abstract the asynchronous calls will most likely be void. But the key is last parameter. This delegate allows me to specify how I want to deal with the result.

Now I create a project that is solely used to implement ICalculator and connect with the web service. First, if you haven't read my post about abstracting WCF service calls, be sure to read it: Abstracting WCF Service Calls in Silverlight. It explains how I use a base class to avoid having to change the ServiceReferences.ClientConfig file everytime I deploy an application, and also will give you the concept for the BaseService class you see below.


public class CalculatorService : BaseService<CalculatorServiceClient,ICalculatorService>, ICalculator
{
    public CalculatorService()
    {
        _GetClientChannel().MultiplyCompleted += new EventHandler<MultiplyCompletedEventArgs>(CalculatorService_MultiplyCompleted);
    }        

    #region Event handlers

    void CalculatorService_MultiplyCompleted(object sender, MultiplyCompletedEventArgs e)
    {
        Action<long> result = e.UserState as Action<long>;
        if (result != null)
        {
            result(e.Result); 
        }
    }

    #endregion 

    #region ICalculator Members

    public void Multiply(int x, int y, Action<long> result)
    {
        _GetClientChannel().MultiplyAsync(x, y, result);
    }

    #endregion
}

The base class preps the channel and credentials, etc for me. In the constructor of the implementation, I simply register for the completion event for the call. When a consumer of the service makes a call, the consumer provides a delegate to call back to when the service is done. This is passed in the user state, then cast back to an action and called once the service returns. If you wanted to have error handling, you'd just extend the action delegate to have an error-related parameter and check the e.Error when the call completed.

Now we can put it into use. In my bootstrapper, I'll bind the service to the contract like this:


Container.RegisterType<ICalculator,CalculatorService>(new ContainerControlledLifetimeManager());
            

Now I can throw a view model together that looks something like this:


public class CalculatorViewModel : INotifyPropertyChanged
{

    private bool _busy = false;

    public bool BusyState
    {
        get { return _busy; }
        set
        {
            if (!value.Equals(_busy))
            {
                _busy = value;
                OnPropertyChanged("BusyState");
                CalculateCommand.RaiseCanExecuteChanged();
            }
        }
    }

   public DelegateCommand<object> CalculateCommand { get; set; } 

    public CalculatorViewModel(ICalculator calculator)
    {
        Calculator = calculator;
        CalculateCommand = new DelegateCommand<object>(o => CommandCalculate(),
            o => !BusyState);
    }

    public ICalulator Calculator { get; set; }

    private int _x;

    public int X
    {
        get { return _x; }
        set
        {
            if (!value.Equals(_x))
            {
                _x = value;
                OnPropertyChanged("X"); 
            }
        }
    }

     private int _y;

    public int Y
    {
        get { return _y; }
        set
        {
            if (!value.Equals(_y))
            {
                _y = value;
                OnPropertyChanged("Y"); 
            }
        }
    }

    private long _answer;

    public long Answer
    {
        get { return _answer; }
        set
        {
            if (!value.Equals(_answer))
            {
                _answer = value;
                OnPropertyChanged("Answer"); 
            }
        }
    }

    public void CommandCalculate()
    {
        BusyState = true;
        Calculator.Multiply(_x, _y, answer => {
              BusyState = false;
              Answer = answer;
         }); 
    }

    private void OnPropertyChanged(string property)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(property));
        }
    }

    #endregion 

    #region INotifyPropertyChanged Members

   public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

Now I can simply data bind my XAML to the X, Y, and Answer properties, and bind a button to the Click command. The button will even disable itself while the client is waiting on the server to return the answer. As you can see, the implementation is very straightforward and I don't have to worry about how the call happens. In fact, using this type of abstraction, I could easily wire in a mock class to satisfy the service for testing like this... or maybe decide that a web service for multiplication is overkill and just satisy the contract locally:


public class MockCalculator : ICalculator 
{
   public void Multiply(int x, int y, Action<long> result) 
   {
      result(x*y);
   }
}

While the Action command is really a different way of expressing a delegate, it also makes the intent of the code clear and allows for a clean separation of mechanism from result when dealing with asynchronous calls.

Jeremy Likness