I am writing a Portable Class Library to be shared by desktop and WP8. In the library there is a method to get data from a website, in which method a chain of web requests have to be made in synchronized way and in certain order, result from each response feeds the next request, only the final response is interesting to user.

If this is a desktop .NET library, I would use GetResponse() and have all the logic in one method. I would invoke this whole method in a background thread to avoid blocking UI interaction.

In PCL/WP8 there's only BeginGetResponse(), is there a design pattern or syntactic sugar I can leverage to write the synchronized call chain in a sequential way instead of having a bunch of callback methods?

有帮助吗?

解决方案

HttpClient would be a better choice. If you can't use it for any reason, wrap BeginGetResponse/BeginGetResponse with Task.Factory.FromAsync, as an extension method:

static public Task<WebResponse> GetResponseAsTaskAsync(this WebRequest @this)
{
    return Task.Factory.FromAsync(
         (asyncCallback, state) =>
             @this.BeginGetResponse(asyncCallback, state),
         (asyncResult) =>
             @this.EndGetResponse(asyncResult), null);
}

Then you do a blocking call like this:

var response = request.GetResponseAsTaskAsync().Result;

If you do a series of request, one after another, you should keep this logic asynchronous and let the client of your PCL library to decide whether to block or not. Something like this:

static public async Task<WebResponse> GetManyResponsesAsync(string[] urls)
{
    WebResponse lastResponse = null;
    foreach (url in urls)
    {
        var request = WebRequest.Create(url);
        var response = await request.GetResponseAsTaskAsync();
        // .. process response
        lastResponse = response;
    }
    return lastResponse;
}

The caller would have a choice to await on the result of GetManyResponsesAsync, or block with GetManyResponsesAsync().Result.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top