Thinking Async 1 – Asynchronous Data Access in Silverlight

I have created a simple example of how you can do asynchronous business objects in a Silverlight application using a WCF service reference. This example is very simple and is not as fully abstracted as it could be but I am simply focusing on the aspects of retrieving data asynchronously and putting them into your business objects for now.

Download this examples source.

The first key is in the factory method, let’s see an example.

public static ExampleCollection FetchAll()

{

    ExampleServiceSoapClient client = new ExampleServiceSoapClient();

    client.FetchAllCompleted += (sender, e) =>

    {

        ExampleCollection collection = e.UserState as ExampleCollection;

        collection.Load(e.Result);

    };

 

    ExampleCollection examples = new ExampleCollection();

    client.FetchAllAsync(examples);

    return examples;

}

 

In the example factory above we are attaching an event handler to the FetchAllCompleted handler of our WCF service client. This would normally be abstracted out into a Data Access Provider layer but for the sake of simplicity we are doing it using an inline lambda expression.

Next we are creating a new, empty, collection then calling FetchAllAsync then passing back the example collection to the caller. At this point the collection will actually be empty and at some time in the future the asynchronous call will complete and begin adding objects to the collection. This is important because for data binding we need the object we wish to be bound to immediately but we don’t necessarily need its data.

In order to notify the caller that we have added objects to our collection asynchronously we will need our collection to implement INotifyCollectionChanged. For non-collection objects you will need to implement INotifyPropertyChanged. The easiest way to do this for collections is to simply inherit from ObservableCollection<T>.

Here is a simple example of how you might implement a your asynchronous business object collection

public class ExampleCollection : ObservableCollection<Example>

{

    private void Load(ExampleInfo[] exampleInfo)

    {

        foreach (ExampleInfo info in exampleInfo)

        {

            this.Add(new Example(info));

        }

    }

 

    public static ExampleCollection FetchAll() …

}

 

Here is an example of a non-collection business object

public class Example : INotifyPropertyChanged

{

    public Example(ExampleInfo exampleInfo)

    {

        Load(exampleInfo);

    }

 

    private Example() { }

 

    private int _id;

    private string _name;

 

    public int ID

    {

        get { return _id; }

        private set

        {

            _id = value;

            OnPropertyChanged(“ID”);

        }

    }

 

    public string Name

    {

        get { return _name; }

        set

        {

            _name = value;

            OnPropertyChanged(“Name”);

        }

    }

              

    private void Load(ExampleInfo exampleInfo)

    {

        ID = exampleInfo.ID;

        Name = exampleInfo.Name;

    }

 

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)

    {

        if (PropertyChanged != null)

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

    }

 

    public static Example Fetch(int id)

    {

        ExampleServiceSoapClient client = new ExampleServiceSoapClient();

        client.FetchCompleted += (sender, e) =>

        {

            Example example = e.UserState as Example;

            example.Load(e.Result);

        };

 

        Example ex = new Example();

        client.FetchAsync(id, ex);

        return ex;

    }

}

 

Remember, you just have to think in async!

Author: justinmchase

I'm a Software Developer from Minnesota.

Leave a Reply

Discover more from justinmchase

Subscribe now to keep reading and get access to the full archive.

Continue reading