How do you wait/join on a WCF Web Service called from Silverlight?

If you call a web service from Silverlight like this:

MyServiceClient serviceClient = new MyServiceClient();
void MyMethod()
{
  serviceClient.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(serviceClient_GetDataCompleted);
  serviceClient.GetDataAsync();

  // HOW DO I WAIT/JOIN HERE ON THE ASYNC CALL, RATHER THAN BEING FORCE TO LEAVE THIS METHOD?

}

I would rather wait/join with the asych service thread inside "MyMethod" rather than leaving "MyMethod" after calling "GetDataAsync", what is the best way to do this?

Thanks, Jeff

Answers


To do this you would use a ManualResetEvent in your class (class level variable) and then wait on it.

void MyMethod()
{
  wait = new ManualResetEvent(false);
  // call your service
  wait.WaitOne();
  // finish working
}

and in your event handler code

void serviceClient_GetDataCompleted(...)
{
  // Set values you need from service
  wait.Set();
}

No you cannot do this way. You will end up in a deadlock. GetDataCompleted is called by the mainthreed. The same threed thait is waiting in WaitOne.


I have to ask; why? The point is to provide your user with a fluid experience and waiting on a web service call will not necessarily do that. I suppose you want the full block of content to load before the Silverlight control loads. In that case, I would turn to caching the content rather than forcing the client to wait indefinitely.


You could also use a lambda and closure to get similar behavior:

serviceClient.GetDataCompleted += (s,e) =>
{
  // Your code here
};
serviceClient.GetDataAsync();

If you had a base class provide the mechanics of building a WCF channel, it could then be used to build the BeginX / EndX methods for a async call.

public class ServiceFooCoordinator : CoordinatorBase<IServiceFoo>
{
    public IAsyncResult BeginMethodFoo ()
    {
        IAsyncResult ar = null;
        IServiceFoo channel = null;
        channel = _factory.GetChannel();

        Begin( channel, () => ar = channel.BeginMethodFoo( null, channel ) );
        return ar;
    }

    public Bar[] EndMethodFoo ( IAsyncResult ar )
    {
        IServiceFoo channel = null;
        channel = _factory.GetChannel();
        return channel.EndMethodFoo( ar );
    }
}

Which can then be used in a method:

 ServiceFooCoordinator _coordinator;

 var asyncResult = _coordinator.BeginMethodFoo();
 try
 {
   var result = _coordinator.EndMethodFoo( asyncResult );
 }
 catch ( Exception )
 { }

Which gets you your asynchronous call in a sychronous manner.


Need Your Help

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5

java arrays indexoutofboundsexception

I need help with a little array assignment that I am currently doing. So far I managed to correct alof of code but this one problem still remains..

javac goes crazy on CPU utilization ECJ is able to maintain a predictable CPU utilization for a multi-threaded Producer -Consumer

java eclipse multithreading javac cpu-usage

I was running a 1 Producer thread, 1 Consumer thread problem with a shared buffer and a temporary cache (of 1000 elements).