Calling a webservice synchronously from a Silverlight 3 application?

Posted by Lasse V. Karlsen on Stack Overflow See other posts from Stack Overflow or by Lasse V. Karlsen
Published on 2010-05-28T10:10:34Z Indexed on 2010/05/28 12:41 UTC
Read the original article Hit count: 159

I am trying to reuse some .NET code that performs some calls to a data-access-layer type service. I have managed to package up both the input to the method and the output from the method, but unfortunately the service is called from inside code that I really don't want to rewrite in order to be asynchronous.

Unfortunately, the webservice code generated in Silverlight only produces asynchronous methods, so I was wondering if anyone had working code that managed to work around this?

I tried the recipe found here: The Easy Way To Synchronously Call WCF Services In Silverlight, but unfortunately it times out and never completes the call.

Or rather, what seems to happen is that the completed event handler is called, but only after the method returns. I am suspecting that the event handler is called from a dispatcher or similar, and since I'm blocking the main thread here, it never completes until the code is actually back into the GUI loop.

Or something like that.

Here's my own version that I wrote before I found the above recipe, but it suffers from the same problem:

public static object ExecuteRequestOnServer(Type dalInterfaceType, string methodName, object[] arguments)
{
    string securityToken = "DUMMYTOKEN";
    string input = "DUMMYINPUT";
    object result = null;
    Exception resultException = null;
    object evtLock = new object();

    var evt = new System.Threading.ManualResetEvent(false);
    try
    {
        var client = new MinGatServices.DataAccessLayerServiceSoapClient();
        client.ExecuteRequestCompleted += (s, e) =>
        {
            resultException = e.Error;
            result = e.Result;
            lock (evtLock)
            {
                if (evt != null)
                    evt.Set();
            }
        };
        client.ExecuteRequestAsync(securityToken, input);
        try
        {
            var didComplete = evt.WaitOne(10000);
            if (!didComplete)
                throw new TimeoutException("A data access layer web service request timed out (" + dalInterfaceType.Name + "." + methodName + ")");
        }
        finally
        {
            client.CloseAsync();
        }
    }
    finally
    {
        lock (evtLock)
        {
            evt.Close();
            evt = null;
        }
    }

    if (resultException != null)
        throw resultException;
    else
        return result;
}

Basically, both recipes does this:

  • Set up a ManualResetEvent
  • Hook into the Completed event
  • The event handler grabs the result from the service call, and signals the event
  • The main thread now starts the web service call asynchronously
  • It then waits for the event to become signalled

However, the event handler is not called until the method above has returned, hence my code that checks for evt != null and such, to avoid TargetInvocationException from killing my program after the method has timed out.

Does anyone know:

  • ... if it is possible at all in Silverlight 3
  • ... what I have done wrong above?

© Stack Overflow or respective owner

Related posts about web-development

Related posts about Silverlight