Donnerstag, 24. Juni 2010

Synchronizing multiple WCF Service Calls

The scenario is as follows: assume you have a service that delivers articles. It has two methods: GetArticleList, which returns a list of all articles, and GetSpecialOfferArticle which returns a special offer for a given month and year. You want to display the articles in a listbox and higlight the special offer. The point is, that within the client you first need to get the result of GetAllArticles and then the result of GetSpecialOfferArticle. When we do the service call asynchrounsly (like we must do in silverlight), the return order is not guaranteed.

So the article introduces a class called ServiceCallSynchornizer to handle the problem. The idea is to register multiple service calls, cache the results and get notified by an event once all calls are completed. The case described above would then look like:


private ServiceCallSynchronizer sync; 
private ArticleServiceClient proxy ;

private void DoServiceCalls()
{
  proxy = new ArticleServiceClient();
  sync = = new ServiceCallSynchronizer();

  sync.AllCompleted += new EventHandler<EventArgs>(sync_AllCompleted);
  sync.AddServiceCall(new Action<Object>(proxy.GetArticleListAsync), "ArticleList");
  sync.AddServiceCall(new Action<int, int, Object>(proxy.GetSpecialOfferArticleAsync), DateTime.Now.Month, DateTime.Now.Year, "SpecialOffer");
  
  sync.ExecuteAll();
}

private void sync_AllCompleted(object sender, EventArgs e)
{
  ObservableCollection<Article> articles = sync.GetResult<GetArticleListCompletedEventArgs>("ArticleList").Result;
  Article specialOffer = sync.GetResult<GetSpecialOfferArticleCompletedEventArgs>("SpecialOffer").Result;

  ArticleList.ItemsSource = articles;
  ArticleList.SelectedItem = (from art in articles where art.Number == specialOffer.Number select art).FirstOrDefault();
}

Within the DoServiceCalls method we register for the AllCompleted event of the ServiceCallSynchronizer. This event is called when all registered service calls are completed.
Service calls are added using the AddServiceCallMethod. We must pass a delegate into this method as well as the call paramters. This way, the method name and parameters are defined type safe and a check wether the method name exists or not can be done at compile time. The parameter values though are passed as Object[], so they are not type safe at design time, which is a little drawback. But the developer can see the needed parameters within the Action<> definition so it should be ok.
The last parameter passed into the AddServiceCall methods ("ArticleList" / "SpecialOffer" in the example above) are unique keys that we can use to identify the result of our service calls in the AllCompleted event handler. They are mapped to the UserState parameter of the underlying service proxy method.
The usage of this keys can be seen in the sync_AllCompleted method. Using the ServiceCallSynchonizers GetResult<T> method we can obtain the service result by passing in the appropriate key. Because we get notified when all calls are completed, I can use my results in the needed order.

The code can be found here. As usual provided as-is with no warrenties.

The provided solution might help you if you use WCF. If you are free to use other technologies you might choose the Microsoft CCR or the CodePlex project XCoordination Application Space. Ralf Westphal blogged about it and presents these alternatives in detail.

Have fun!

Dienstag, 22. Juni 2010

A tool to compare two WinDbg DumpHeap -stats outputs

As a Silverlight developer one of my favorite tools besides Visual Studio is WinDbg. The native debugger has an extension for silverlight that helps you find memory leaks by showing you why your objects stick in memory.

If you want to know more on how to use it, dont miss Tess Ferrandez's blog ("If broken it is, fix it you should"). Also helpful (and full of further links) was David Ansons blogpost.

One day I found that all the objects I was searching for have been removed from memory. I almost thought that it was donut time, but then I noticed that memory was still slightly increasing over time.

The sos-extension for WinDbg offers a command called !DumpHeap -stat which dumps out all the objects on the managed heap. To find my leak I decided to take a dump, do something with my app, take a second dump and then compare the two dumps to see which new objects had been created.

To be able to compare the two dumps effectivly I wrote a small tool. Simply copy the dump from WinDbg via <Ctrl>+C and click on the "Paste" button above the corresponding textbox. Pasting the text directly to the textbox using <Ctrl>+V did not work for me, the text was chopped of. Dont know why, so I added the copy button. As soon as you copy the second dump to the second window, the text input is converted into a joined dataset and the comparrison result is shown in the lower pane.

The tool also calculates the "increasement factor" and colorizes the new count green or red depending on wether the number of objects increased or decreased (or is the same).

You can download the code here. The code is provided "as is" with no warrenties. Have fun!

Donnerstag, 17. Juni 2010

A great MVVM view model base class for SL4 - Part II

In my previous post I mentioned the view model base class of Brian Genisio. It uses a dictinary as a value storage for your view models properties. In your view model you write the following:

public class MyViewModel : ViewModelBase
{
  public string Name
  {
    get { return Get(() => Name); }
    set { Set(() => Name, value); }
  }
}

The expression "() => Name" is used instead of the string "Name" to identify the property in a strong typed manner (that means you could have also written Get("Name") instead).

All this works fine as long as your view model orignially provides all the values you need. In my case I have view models that use model classes as data storage like so:

public class MyViewModel : ViewModelBase
{
  private Person m_Person;
  public string Name
  {
    get { return m_Person.Name; }
    set
    {
      if (m_Person.Name != value)
      {
        m_Person.Name = value;
        OnPropertyChanged("Name");
      }
    }
  }
}

That forces me to write all the set-code myself again. My idea to be able to use all the base class goodies again was to add an additional but optional business object to the base class as well as some new overloads to the Get / Set methods:

public class ViewModelBase : INotifyPropertyChanged
{
  private Object m_BusinessObject;

  public ViewModelBase() : this(null)
  { }

  public ViewModelBase(Object BusinessObject)
  {
  m_BusinessObject = BusinessObject;
  ...
  }

  protected T Get<TBusniessObject, T>(Expression<Func<T>> expression, T DefaultValue)
  {
    if (m_BusinessObject == null)
      return DefaultValue;

    String propName = GetPropertyName(expression);
    return (T)m_BusinessObject.GetType().GetProperty(propName).GetValue(m_BusinessObject, new object[] { });
  }

  protected void Set<TBusinessObject, T>(Expression<Func<T>> expression, T value)
  {
    if (m_BusinessObject == null)
      return;

    if (Get<TBusinessObject, T>(expression).Equals(value))
      return;

    String propName = GetPropertyName(expression);
    m_BusinessObject.GetType().GetProperty(propName).SetValue(m_BusinessObject, value, new object[] { });
    Set(propName, value);
  }

}


The idea is simple: as long as the business object is not null we get / set the value out of it via reflection. In the setter we first compare the current value with the acutal one to leave if nothing has changed. After having set the value to the business object, I pass the value through to the normal Set method in order to get all the other gadgets like dependent methods working.

With that code in place I am able to write the Property from my above example like so:

public class MyViewModel : ViewModelBase
{
  private Person m_Person;
  public string Name
  {
    get { Get<Person, string>(() => Name); }
    set { Set<Person, string>(() => Name, value); }
  }
}

Brians code is at codeplex. My suggestions can easily be incorporated.

Have fun.

A great MVVM view model base class for SL4

Brian Genisio blogged about a MVVM ViewModel base class with lots of fantastic features to save you from writing too much plumbing code. You can read about it in his blog:

My view model base
My view model base - Silverlight support

To me, this base class contains of two basic ideas.
  1. The first idea is that you do not need to write all those ICommand-type properties yourself but let them generate dynamically from methods that are named by the convention Execute_< commandname > / CanExecute_< commandname >. The properties are stored within a dictionary within the base class.
  2. The second idea is not to write all these OnPropertyChanged notification code all the time you publish a property in your view model, but let the base class do it. For this reason the base classes dictionary (the same on in which the ICommand-properties are stored) acts as a value storage for all your property values. Within your view model you only call a base class method to get and set the value. Therby all get /set code runs thorugh a central point that handles the OnPropertyChanged-stuff.

Up to Silverlight 3 there was a problem with data binding of these "dynamic" properties, because in contrast to WPF Silverlight was not able to bind against dictionaries. The workaround was to use a value converter to do the magic.

With Silverlight 4 it is possible to bind against indexers using the following syntax:


< button type="submit" command="{Binding" content="Click me" />

Note the square brackets around the command name - they indicate that the name inside the brackets is to be interpreted as the key of the indexer and yields to

MyViewModelInstance["ButtonClick"]

With this new feature in place, the value converter is no longer needed, which makes the code more readable.

Brian hosted all the sourcecode on codplex.

Thanks for sharing!