30 Mar 2009

Silverlight 3 Quick Tip : Lambda Expressions for Async Web Service Calls

   

(this should work in SL2 as well)

All network calls in Silverlight are asynchronous. The proliferation of event handling functions this can cause just makes for really cluttered code. Using lambda expressions seems to make my code a bit cleaner. (You can also use regular anonymous delegates, but the lambdas involve less typing)

public void LoadPolicyDetail()
{
    IvcDataServiceClient client = new IvcDataServiceClient();

    client.GetPolicyDetailCompleted += (s, e) =>
    {
        if (e.Result != null)
        {
            _policyDetail = e.Result;

            if (PolicyDetailLoaded != null)
                PolicyDetailLoaded(this, new EventArgs());
        }
        else
        {
            if (PolicyDetailLoadError != null)
                PolicyDetailLoadError(this, new EventArgs());
        }
    };

    client.GetPolicyDetailAsync();
}
The event handler is right in-line with the loading function. The event args remain strongly typed, so you have access to everything you normally would with an additional function.

In the example above, PolicyDetailLoaded and PolicyDetailLoadError are events I raise from my ViewModel, and GetPolicyDetailCompleted is the async call-completed event on the WCF client proxy.

Share |
posted by Pete Brown on Monday, March 30, 2009
filed under:    

11 comments for “Silverlight 3 Quick Tip : Lambda Expressions for Async Web Service Calls”

  1. Sergey Barskiysays:
    Would this introduce a memory leak or two event handlers if LoadPolicyDetail is called twice?

    Thanks.
    Sergey Barskiy.
  2. JWCsays:
    I like it. Thanks.
  3. Pete Brownsays:
    @Sergey I ran this across some other folks, and while this is by no means a definitive, verified answer, general concensus is that it will not leak.

    The lambda and wcf client are both eligable for collection after the GetPolicyDetailCompleted event is fired.

    If anyone wants to profile this and provide a definitive answer, I'll post the results.

    Pete
  4. samcovsays:
    Yes, this not only works fine in SL2, using Lambda functions works well for all other events as well.

    I love the way I don't have to declare the event type and sender, the Lambda just infers it... sweet!
  5. Mark Monstersays:
    Hi Pete,

    I've done similar things with lambda's. They really help making asynchronous code more readable.
    http://mark.mymonster.nl/2008/08/03/using-function-pointers-a-la-eventhandlert-instead-of-return-types/

    --
    Mark Monster
  6. Andreasays:
    Great! Does it works also on SL2?
  7. Marksays:
    If only VB had multi-line lambdas.... NOW :)
  8. Andrea Boschinsays:
    Hi Pete,

    I write a post most similar to your some months ago but it is slightly different. In my sample I've user Action<T> to forward success and fail of the asyncronous method to the caller. This is because I prefer to incapsulate service calls in a layer and let the caller doing his work with the results.

    http://blog.boschin.it/archive/2008/12/04/Silverlight-Gestire-la-comunicazione-asincrona.aspx
  9. Marc Perronesays:
    This looks nice but do you really want the overhead of creating a new client and lambda object every time you need to make a service call?
  10. Pete Brownsays:
    @Marc

    I typically did not reuse clients anyway, so it isn't a big deal. The overhead is pretty minimal.

    Creating new clients for each call let me both keep the code small and functional, and not lose track of which return came from which service call.

    Now, if you need to make a bunch of highly related calls, you may not want to go this route. I try to minimize service calls if possible (having larger calls rather than chatty calls), as those are the main performance sinks in a RIA

    Pete

Comment on this Post

Remember me