Calling a service from Windows Phone application reactively

If you are creating connected Windows Phone application then most probably have noticed that mostly interface what Visual Studio (VS) generates for you in client proxy class is event-based async pattern.

For instance we have defined service (usually this is WCF implementation) method:

 

public class AtmFinderService : IAtmFinderService
{
    public ServiceResponse FindNearby(double latitude, double longitude)
    {
        ...
    }

 

Generating the client proxy class we can see that VS generated event based approach, when we do have an incredible opportunity to use DoSomethingAsync() method in our favor and then try to catch event which is raised immediately after operation has been completed.

 

 

Using this method and event code does look pretty much readable (we will touch body of the event handler later on as well).

 

proxy.FindNearbyCompleted += (sender, args) =>
                                 {
                                     // do something
                                 };

 

Suppose if you are sharing the proxy class (for instance, as static member of your service façade). Then for sure you will need a mechanism how you can unsubscribe from the event after method has been executed successfully. More info on subscribing and unsubscribing to the events here - http://msdn.microsoft.com/en-us/library/ms366768.aspx.

So, what we can do is to define event handler and store the reference to the body in class field or member. We can define variable as delegate:

 

EventHandler<FindNearbyCompletedEventArgs> delg = delegate(object sender, FindNearbyCompletedEventArgs args)
                                                      {
                                                          // do something
                                                      };

 

or we can define to store as EventHandler:

 

var delg = new EventHandler<FindNearbyCompletedEventArgs>((sender, args) =>
                                                              {
                                                                  // do something
                                                              });

 

Then I figured out that the most easiest way to subscribe only once per call is to unsubscribe first and then subscribe:

 

proxy.FindNearbyCompleted -= delg;
proxy.FindNearbyCompleted += delg;

 

When next time method will be executed event handler added from previous call will be removed first, and then added new one.

Then we can proceed with the actual service method call. So the complete code is:

 

var delg = new EventHandler<FindNearbyCompletedEventArgs>((sender, args) =>
                                                              {
                                                                  // do something
                                                              });

proxy.FindNearbyCompleted -= delg;
proxy.FindNearbyCompleted += delg;

proxy.FindNearbyAsync(location.Latitude, location.Longitude);

 

This is more or less everything you need to call service method from Windows Phone in async event-based pattern.

One more note about event handler body. Usually there is requirement to execute event handler on the Dispatcher if that updates something in user interface from another thread (that may happen if event handler is called later on).

 

var delg = new EventHandler<FindNearbyCompletedEventArgs>((sender, args) =>
            {
                if (Deployment.Current.Dispatcher.CheckAccess())
                {
                    Deployment.Current.Dispatcher.BeginInvoke(/* method */);
                    return;
                }

                // do something
            });

 

Here comes another problem that we need to call the same event handler body only within the Dispatcher context.

Easiest way to implement this requirement would be to implement additional method as event handler and then perform dispatcher check there and if call requires dispatcher context, invoke the same method once more within dispatcher context.

So we are implementing the event handler method first.

 

private void ProxyOnFindNearbyCompleted(object sender, FindNearbyCompletedEventArgs args)
{
    if (!Deployment.Current.Dispatcher.CheckAccess())
    {
        Deployment.Current.Dispatcher.BeginInvoke(new Action<object, FindNearbyCompletedEventArgs>(ProxyOnFindNearbyCompleted),
                                                  sender,
                                                  args);
        return;
    }

    // do something
}

 

And then the original code that attaches the event handler and calls the method remains almost the same:

 

proxy.FindNearbyCompleted -= ProxyOnFindNearbyCompleted;
proxy.FindNearbyCompleted += ProxyOnFindNearbyCompleted;

proxy.FindNearbyAsync(location.Latitude, location.Longitude);

 

However for me this all seems already converting into unreadable spagetti-like code set.

There is a more elegant way to accomplish this. I’m going to use Reactive Extensions for Windows Phone – Microsoft.Phone.Reactive. Library is coming with Windows Phone SDK.

 

 

At first we are defining observable from the event-based async pattern.

 

var completedObservable = Microsoft.Phone.Reactive.Observable.FromEvent<FindNearbyCompletedEventArgs>(
    ev => proxy.FindNearbyCompleted += ev,
    ev => proxy.FindNearbyCompleted -= ev);

 

Those two arguments for FromEvent() method is used to add event handler and to remove event handler for FindNearbyCompleted event. This is also an elegant way how to write code that subscribes to the event only once.

When observable has been created we are able to subscribe to to the event and provide handler to execute when event is raised.

 

completedObservable.Subscribe(result =>
                                  {
                                      // do something
                                  });

 

The complete code looks like following:

 

var completedObservable = Observable.FromEvent<FindNearbyCompletedEventArgs>(
    ev => proxy.FindNearbyCompleted += ev,
    ev => proxy.FindNearbyCompleted -= ev);

completedObservable.Subscribe(result =>
                                  {
                                      // do something
                                  });

proxy.FindNearbyAsync(location.Latitude, location.Longitude);

 

Pretty straight forward and what’s important – code is readable and understandable.

One more thing, if you require to run event handler on Dispatcher thread, than that’s far more easier than previous implementation with direct checking dispatcher access. You just have to tell reactive extensions that you need to observe events on dispatcher thread rather than on current context.

 

completedObservable.ObserveOnDispatcher().Subscribe(result =>
                                                        {
                                                            // do something
                                                        });

 

 

In summary, code gets reduced, more readable and understandable.

Hope this helps!

Published Wednesday, June 20, 2012 9:36 AM by valdis.iljuconoks

Leave a Comment

(obligāts) 
(obligāts) 
(brīvizvēles)
(obligāts)