views:

70

answers:

3

I'm currently having to integrate a lot of web service calls inside Silverlight that make calls similar to the code below. No user interaction should be possible until the loading of all 3 is complete.

// In my view, having standard delegate methods (non-anonymous) makes the 
// code below even messier.

// I've left out the EventArgs to shorten the example however
// I usually use these objects in the delegate method.
MyService1 service1 = new MyService1();
service1.GetAllUsersCompleted += delegate
{
    MyService2 service2 = new MyService2();
    service2.AnotherTaskCompleted += delegate
    {
        MyService3 service3 = new MyService3();
        service3.YetAnotherTaskCompleted += delegate
        {
            // etc.
        };
        service3.YetAnotherTask();
    };
    service2.AnotherTask();
};
service1.GetAllUsers();

Essentially I would like the calls to be synchronous however because of the architecture of web service proxy classes in Silverlight (everything is event driven) I can't do this.

My question is, is there a more elegant solution or possibly a .NET centric design pattern for refactoring what I have away from one delegate method calling another method, calling another, into something that is easier to manage?

One of my biggest issues with the code is the actual method call comes after the bulk of the work in the delegate.

+1  A: 

I think this is what the new Tasks (in the Parallel library) classes try to abstract, but I could be wrong :)

leppie
A: 

I might be wrong here but aren't delegates already syncrhonous. You can make them asynchronous by using the BeginInvoke method. Here is a good resource for syncronous and asynchronous method calls and explains some patterns etc. http://support.microsoft.com/kb/315582

The title of the article may be How to call a Visual C# method asynchronously but there are example of synchronous method calls about half way through.

uriDium
The issue is all web service references are event driven
Chris S
+1  A: 

Well, I'd recommend first that you take advantage of the asynchronous nature of Silverlight by running all three calls simultaneously, if possible.

You could do this "sequentially" with tasks (task continuations, in particular), but you may also want to look at the Rx library, which is designed to gracefully handle this kind of situation.

Another final tip: disallowing user interaction isn't recommended. At least give them the option of cancelling the operation.

Stephen Cleary