Three Ways to Handle Silverlight Asynchronous Service Calls

March 16, 2010 at 8:48 AMmgordon

In Each of the examples, below, I’ll show the code that in the ViewModel and also in a service layer class that handles talking to the actual service.

One – Callback

public class ViewModel
{
    var _dataService = new DataService();

    private void GetData()
    {
        _dataService.GetCustomers(GetCustomersCallback);
    }

    private void GetCustomersCallback(object sender, GetCustomersCompletedEventArgs e)
    {
        Customers = e.Result;
    }
      
}

 

public class DataService
{
    var _client = new MyWCFServiceClient();

    public void GetCustomers(EventHandler<GetCustomersCompletedEventArgs> callback)
    {
        _client.GetCustomersCompleted += new EventHandler<GetCustomersCompletedEventArgs>(callback);
        _client.GetCustomersAsync();
    }
}

 

This approach really just extends the model that is generated in the proxy file for the service.  The ViewModel is called back on the callback method and the results of the call are available there for use.  To use a lambda expression and avoid having to write the separate callback method, you could do something like the below in the ViewModel.

 

public class ViewModel
{
    var _dataService = new DataService();

    private void GetData()
    {
        _dataService.GetCustomers( (o, e) =>
        {
            Customers = e.Result;
        });
    }
}

 

Two – Event

public class ViewModel
{
    var _service = new DataService();

    public ViewModel()
    {
        _service.CustomersLoaded += CustomerLoadCompleted;
    }

    private void CustomerLoadCompleted(object sender, ObservableCollection<Customer> customers)
    {
        Customers = customers;
    }
}

 

public class DataService
{
    var _client = new MyWCFServiceClient();

    public event EventHandler<<ObservableCollection<Customer>> CustomersLoaded;

    public DataService()
    {
        _client.GetCustomersCompleted += GetCustomersLoadedHandler;
    }

    void GetCustomersLoadedHandler(object sender, GetCustomersCompletedEventArgs e)
    {
        if (CustomersLoaded != null)
        {
            CustomersLoaded(sender, e.result);
        }
    }
    public void  GetCustomers()
    {
        _client.GetCustomers();
    }
}

 

Here, we let the data service raise an event to the ViewModel when the service call is completed.  This approach doesn’t gain us much unless there are multiple objects that need to be notified when the service call completes.

 

Three – Fake Synchronous Call

 

public class ViewModel
{
    var _service = new DataService();

    public ViewModel()
    {
        Customers = _service.GetCustomers();
    }

}

public ObservableCollection<Customer> GetCustomers()
{
    ObservableCollection<Customer> customers;

    _client.GetCustomersCompleted += (o, e) => 
    {
        customers = e.Result;
        re.set;
    }

    _client.GetCustomersAsync();
    re.WaitOne(1000);
    return customers;
}

 

So, here we’re using a ManualResetEvent to wait for the service call to complete.  We’ll wait for one second for the event to be set before we abandon the results and just return.  Use caution when using this approach as blocking a browser thread will totally freeze the UI.

Posted in: Silverlight

Tags: