DCSIMG
What happened to asynchrony with WebClient in .NET 4.5? - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

What happened to asynchrony with WebClient in .NET 4.5?

In the Visual Studio 2010 Async CTP, a bunch of extension methods have been added to the WebClient class, to facilitate the “awaiting” of C# 5.0, such as DownloadStringTaskAsync, which can be simply used like so:

  1. var wc = new WebClient();
  2. string result = await wc.DownloadStringTaskAsync("http://msdn.microsoft.com");

One of the overloads present in the CTP accepts a CancellationToken, so that the operation could be cancelled by an external CancellationTokenSource. For example:

  1. async Task<string> GetData(string uri, CancellationToken token) {
  2.     var wc = new WebClient();
  3.     string result = await wc.DownloadStringTaskAsync(new Uri(uri), token);
  4.     return result;
  5. }

So, the typical caller can use it like so:

  1. CancellationTokenSource _cts;
  2.  
  3. private async void OnGetData(object sender, RoutedEventArgs e) {
  4.     var wc = new WebClient();
  5.     _cts = new CancellationTokenSource();
  6.     try {
  7.         string result = await wc.DownloadStringTaskAsync(new Uri("http://www.codevalue.net"), _cts.Token);
  8.         _data.Text = result;
  9.     }
  10.     catch(OperationCanceledException ex) {
  11.         _data.Text = "Cancelled";
  12.     }
  13. }

Calling CancellationTokenSource.Cancel causes cancellation, delivered as an OperationCancelledExcpetion exception. The actual Cancel would be typically invoked from some event handler:

  1. private void OnCancel(object sender, RoutedEventArgs e) {
  2.     if(_cts != null)
  3.         _cts.Cancel();
  4. }

In .NET 4.5, I was expecting the WebClient class to have all the extension methods baked into the type as instance methods. The basic DownloadStringTaskAsync method is there, but with no overload that accepts a CancellationToken. Where did that go?

Well, it turns out that WebClient has lost its attraction. There is a new guy in town – HttpClient. It’s a complete replacement for WebClient (and also HttpWebRequest). It’s built with “async” in mind – all its operations are asynchronous, never synchronous. So, the way to allow cancellation while awaiting is to use HttpClient:

  1. _cts = new CancellationTokenSource();
  2. try {
  3.     var result = await client.GetAsync("http://www.codevalue.net", _cts.Token);
  4.     var data = await result.Content.ReadAsStringAsync();
  5.     _data.Text = data;
  6.     _cts.Dispose();
  7.     _cts = null;
  8. }
  9. catch(OperationCanceledException ex) {
  10.     _data.Text = "Cancelled";
  11. }

Note that even getting the actual string is an asynchronous operation (there is a GetStringAsync on HttpClient, but it cannot accept a CancellationToken).

HttpClient is the new HTTP king: it can do anything WebClient and HttpWebRequest can do (plus some more), and all is asynchronous – perfect to use with the new C# 5.0 async feature.

Comments List

# Operationcanceledexception interop | Bangkoksightse

Published at Friday, July 06, 2012 7:38 PM by Operationcanceledexception interop | Bangkoksightse  

Pingback from  Operationcanceledexception interop | Bangkoksightse

Leave a Comment

(required) 
(
required
)
 
(optional)
(required) 

Enter the numbers above: