开发者

Handling multiple async HTTP requests in Silverlight serially

D开发者_运维技巧ue to the async nature of http access via WebClient or HttpWebRequest in Silverlight 4, when I want to do multiple http get/posts serially, I find myself writing code that looks like this:

doFirstGet(someParams, () =>   
  {
    doSecondGet(someParams, () =>
      {
        doThirdGet(...
      }   
  });

Or something similar. I'll end up nesting subsequent calls within callbacks usually implemented using lambdas of some sort. Even if I break things out into Actions or separate methods, it still ends up being hard to read.

Does anyone have a clean solution to executing multiple http requests in SL 4 serially?

I don't need the code that actually kicks all of this off to be synchronous, but I need the requests to happen serially, so each request needs to be effectively synchronous.


Take look at a couple of my blog posts on this:-

Simple Asynchronous Operation Runner – Part 1
Simple Asynchronous Operation Runner – Part 2

The articles are a little in depth because they focus on the actual implementation, the idea is not have to include fancy frameworks just to get this done. The only code you need is actually there in the articles, no additional dlls or zip files to download.

However note in part 2 the approach of imagining what your code would look like if synchronous coding were possible. In your case your code would look like this:-

void StuffToDo()
{
    doFirstGet(someParams);
    doSecondGet(someParams);
    doThirdGet(...);
}

The next step is modify the content of the "do" methods to return an AsyncOperation instead. Currently they probably look something like this:-

void doFirst(someParams, Action callback)
{
    SomeAsyncObj thing = new SomeAsyncObj();
    thing.OnCompleted += (s, args) { callback() };
    thing.DoSomethingAsync();
} 

You would convert it to:-

AsyncOperation doFirst(someParams)
{
    return (completed) =>
    {
        SomeAsyncObj thing = new SomeAsyncObj();
        thing.OnCompleted += (s, args) =>
        {
            try
            {
                completed(null);
            }
            catch (Exception err)
            {
                completed(err);
            }
        };
        thing.DoSomethingAsync(source);
    };
}

The third step is modify your imaginary synchronous code like this:-

IEnumerable<AsyncOperation> StuffToDo()
{
    yield return doFirstGet(someParams);
    // Do some other synchronous stuff here, this code won't run until doFirstGet has completed.
    yield return doSecondGet(someParams);
    // Do some other synchronous stuff here, this code won't run until doSecondGethas completed.
    yield return doThirdGet(...);
    // Do some final synchronous stuff here, this code won't run until doThirdGethas completed.

}

Finally the call to StuffToDo changes to:-

StuffToDo().Run((err) =>
{
   // report any error in err sensibly
});


I have encountered this problem. I found coroutines to be very helpful, I based my ideas on work by Jeremy Likness and Rob Eisenberg.

This link will give more details.


  1. Encapsulate each request into a class
  2. Create a collection or array of the requests
  3. Iterate through the collection making and processing each request.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜