HttpClient: A Silverlight WebClient Alternative With Cancellation and Timeout Support
Ever since we switched from WCF RIA Services to a ASP .Net Web API for supplying data to our Silverlight application we have been using the System.Net.WebClient class to make the HTTP requests and download the JSON response into Silverlight.
This seemed to be the recommended and most used solution for completing the task we were attempting, but, even in the beginning, some things didn't seem quite right for the use case we had.
Firstly, despite being listed in the .Net Framework 4.5 version of the class, there was no Timeout property available. As it turns out, this is simply a limitation of the Silverlight implementation of the class. This led us to attempt to apply timeout functionality to the class in Silverlight. All attempts at achieving this were unsuccessful.
The result of this was that within the DataAgent class where were declaring and using the WebClient instance we added a timer object, which was set to tick until either:
- The WebClient call returned sucessfully and we stopped the timer from ticking.
- A pre-specified time period elapsed without the data returning and on the next invocation of the tick event, the CancelAsync() method on the WebClient was called, which, according to the MSDN documentation:
Cancels a pending asynchronous operation.
- .NET Framework 4
- .NET for Windows Store apps
- Windows Phone 7.5 and 8
- Silverlight 4 and 5
- Portable Class Libraries
Compared to the severely limited Silverlight WebClient, the HttpClient included within this package is a revelation. It had support for everything that we needed:
- Multiple concurrent operations
- Cancellation via CancellationToken support
- Timeout support either via a property on the HttpClient or via the CancelAfter value set on the provided CancellationToken
- Task Asynchronous Pattern support (thanks to the Async for .NET Framework 4, Silverlight 4 and 5, and Windows Phone 7.5 and 8 NuGet package)
In addition to all of this goodness, there is a support for HTTP Post requests from a named method so we have managed to axe the frankly pretty horrendous WebRequest code we were relying upon!