Good Async pattern for sequential WebClient requests

Most of the code that I wrote in .NET to call REST was synchronous. Since Silverlight on Windows Phone only supports Async WebClient and HttpWebRequest calls, I was wondering what a good asynchronous template is for a class that provides methods that make REST calls.

For example, I have an application that should do the following.

  • Login and get a token
  • Using the token from # 1, get a list of albums
  • Using the token from # 1, get a list of categories
  • etc.

my class provides several methods:

  • To come in()
  • GetAlbums ()
  • GetCategories ()

since each method needs to call WebClient using Async calls, what I need to do is essentially block the Login call until it returns so that I can call GetAlbums ().

What is a good way to do this in my class that provides these methods?

+5
source share
4 answers

It depends on what you want to do with this information. If, for example, you are trying to display a list of albums / categories, etc., One way to simulate this would be

  • , INotifyPropertyChanged ( "" PhoneListApplication).
  • async , callback , async, .
  • async / ObservableList ( ). , , . , , NotifyPropertyChanged , , .

, , - (, , , ). async.

, - , . , , , , , .

+3

Reactive (Rx):

http://www.leading-edge-dev.de/?p=501

http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html

[edit: ooh - :] http://rxwiki.wikidot.com/101samples

"" , , , , "AuthenticationResult Authenticate (string user, string pass)"

- :

var foo = Observable.FromAsyncPattern<string, string, AuthenticationResult>
    (client.BeginAuthenticate, client.EndAuthenticate);
var bar = foo("username","password");
var result = bar.First();

. , "":

var bar = foo("username", "password")
    .Then(authresult => DoSomethingWithResult(authresult));

.:)

+7

async, :

public void MyFunction(
  ArtType arg, 
  Action<ReturnType> success, 
  Action<FailureType> failure);

-, , , , , /. :

MyServiceInstance.MyFunction(
  blahVar,
  returnVal => UIInvoker.Invoke(() => 
    {
      //some success code here
    }),
  fault => UIInvoker.Invoke(() => 
    {
      //some fault handling code here
    }));

(UIInvoker - , .)

+1

- , .

Restful-Silverlight is a library that I created to help with both Silverlight and WP7.

I have included the code below to show how you can use the library to extract tweets from Twitter.

An example of using Restful-Silverlight to get tweets from Twitter:


//silverlight 4 usage
List<string> tweets = new List<string>();
var baseUri = "http://search.twitter.com/";

//new up asyncdelegation
var restFacilitator = new RestFacilitator();
var restService = new RestService(restFacilitator, baseUri);
var asyncDelegation = new AsyncDelegation(restFacilitator, restService, baseUri);

//tell async delegation to perform an HTTP/GET against a URI and return a dynamic type
asyncDelegation.Get<dynamic>(new { url = "search.json", q = "#haiku" })
    //when the HTTP/GET is performed, execute the following lambda against the result set.
    .WhenFinished(
    result => 
    {
        textBlockTweets.Text = "";
        //the json object returned by twitter contains a enumerable collection called results
        tweets = (result.results as IEnumerable).Select(s => s.text as string).ToList();
        foreach (string tweet in tweets)
        {
             textBlockTweets.Text += 
             HttpUtility.HtmlDecode(tweet) + 
             Environment.NewLine + 
             Environment.NewLine;
        }
    });

asyncDelegation.Go();

//wp7 usage
var baseUri = "http://search.twitter.com/";
var restFacilitator = new RestFacilitator();
var restService = new RestService(restFacilitator, baseUri);
var asyncDelegation = new AsyncDelegation(restFacilitator, restService, baseUri);

asyncDelegation.Get<Dictionary<string, object>>(new { url = "search.json", q = "#haiku" })
               .WhenFinished(
               result =>
               {
                   List<string> tweets = new List();
                   textBlockTweets.Text = "";
                   foreach (var tweetObject in result["results"].ToDictionaryArray())
                   {
                       textBlockTweets.Text +=
                           HttpUtility.HtmlDecode(tweetObject["text"].ToString()) + 
                           Environment.NewLine + 
                           Environment.NewLine;
                   }
               });

asyncDelegation.Go();

+1
source

All Articles