views:

457

answers:

2

When writing a Silverlight app hooked up to a WCF Web Service, the only option we are presented with in using the Web Service is to make asynchronous calls to the WS interface.

i.e.

WebService client = new WebService();
client.ServiceMethodCompleted += new EventHandler<Args>(client_Handler);
client.ServiceMethodAsync();
client.close()

...followed by
void client_Handler(object sender, Args e)
{
    //Next step, possibly another method?
}

While I understand the reason for asynchronous calls when writing webapps (safety net), what type of design pattern would one use if a method was written where each step was dependent on the result of the Web Service call?

For instance, if there was a method in the Web Service that checked the user credentials of the visitor, and depending on the group of that user, would perform some action.

public MyPage() //Constructor
{
    CheckCredentialsAsync();

    if(result.IsUserTypeA)
    {
       //something complex
    }
    else if(result.IsUserTypeB)
    {
       //something else complex
    }
    ...etc

}

Is there a way to accomplish this without using a 'domino' design of methods triggered by the previous asynchronous calls completed event? It seems as though it can get messy if there is a lot of client/service interaction.

Thanks!

+2  A: 

The best modeling I know for such patterns is event driven Finite State Machine. Async methods completion are events and your 'complex operations' are actions, your MyPage instance is current state. However FSM can be quite hairy for any fair number of states and events, and while they can be somehow kept in check by composing simpler FSMs, I would not call this pattern intuitive and easy by any stretch.

Frankly I often prefer the chain of callback you describe. The 'domino' effect is not necesarily bad, once you get to write a couple of modules like this you get the hang of it. Its complexity is basically driven by the number of possible execution branches in the 'something complex' blocks. Where in the synchrnous path you'd have an if branch, in the asynchronous path you'd likely have two separate callbacks. Is more code to type, but is not necesarily more difficult to comprehend. And the 'more code' part can be taken care with proper factory of the coe into helpers.

I reckon though that I did not work with the Silverlight classes, my experience is mostly around the WebRequest, SqlClient and Stream operations async behavior. In the end, the most complicated part I find to be the split of the error handling and the split of resource ownership, since the using pattern is far less usefull with async.

Remus Rusanu
+2  A: 

If you don't want to chain callbacks together, check out Jeffrey Richter's AsyncEnumerator: http://www.wintellect.com/PowerThreading.aspx

It supports Silverlight too.

Brannon