views:

76

answers:

2

In my silverlight page, when the user clicks on a button; the app, calls 3 web services async. It has to either wait for these 3 async calls to be completed or has to be notified when these calls are completed. After these 3 calls are completed, the results will be written to a text file (It is a out-of-browser app with elevated trust). Besides writing a timer and poll these calls, is there a better way to be notified when the calls are completed?

A: 

When you invoke a webservice call, you pass in a callback - so you will automatically be notified when the calls are complete.

To track completion, you can use the 'object asyncState' parameter of the beginXXX calls to track each call or you could use a count up / count down integer.

Try this: http://msdn.microsoft.com/en-us/library/cc197937(v=VS.95).aspx

chadbr
+1  A: 

The Reactive Extensions (Rx) library is perfect for this. Take a look here:

http://www.jaylee.org/post/2010/06/22/WP7Dev-Using-the-WebClient-with-Reactive-Extensions-for-Effective-Asynchronous-Downloads.aspx

Scroll to the bottom. Here is an example of waiting for two web client downloads, just substitute whatever your call is for the logic here:

public IObservable<string> StartDownload(string uri)
{
    WebClient wc = new WebClient();

    var o = Observable.FromEvent<DownloadStringCompletedEventArgs>(wc, "DownloadStringCompleted")

                      // Let's make sure that we're not on the UI Thread
                      .ObserveOn(Scheduler.ThreadPool)

                      // When the event fires, just select the string and make
                      // an IObservable<string> instead
                      .Select(newString => ProcessString(newString.EventArgs.Result));

    wc.DownloadStringAsync(new Uri(uri));

    return o;
}

public string ProcessString(string s)
{
    // A very very very long computation
    return s + "<!-- Processing End -->";
}

public void DisplayMyString()
{
    var asyncDownload = StartDownload("http://bing.com");
    var asyncDownload2 = StartDownload("http://google.com");

    // Take both results and combine them when they'll be available
    var zipped = asyncDownload.Zip(asyncDownload2, (left, right) => left + " - " + right);

    // Now go back to the UI Thread
    zipped.ObserveOn(Scheduler.Dispatcher)

          // Subscribe to the observable, and set the label text
          .Subscribe(s => myLabel.Text = s);
}
Jeremy Likness