title: Deciding between HttpClient and WebClient
body: <p>Our web application is running in .NET Framework 4.0. The UI calls the controller methods through Ajax calls.</p>
  <p>We need to consume the REST service from our vendor.   I am evaluating the best way to call the REST service in .NET 4.0.  The REST service requires a basic authentication scheme and it can return data in both XML and JSON.</p>
  <p>There isn't any requirement for uploading/downloading huge data and I don't see anything in future. I took a look at few open source code projects for REST consumption and didn't find any value in those to justify additional dependency in the project. I started to evaluate <code>WebClient</code> and <code>HttpClient</code>. I downloaded HttpClient for .NET 4.0 from <a href="https://en.wikipedia.org/wiki/NuGet" rel="noreferrer">NuGet</a>.</p>
  <p>I searched for differences between <code>WebClient</code> and <code>HttpClient</code> and <a href="https://web.archive.org/web/20140217233914/http://blogs.k10world.com/technology/webclient-httpclient-consume-http-requests/" rel="noreferrer">this site</a> mentioned that single HttpClient can handle concurrent calls and it can reuse resolved DNS, cookie configuration and authentication. I am yet to see practical values that we may gain due to the differences.</p>
  <p>I did a quick performance test to find how <code>WebClient</code> (synchronous calls), <code>HttpClient</code> (synchronous and asynchronous) perform. And here are the results:</p>
  <p>I am using the same <code>HttpClient</code> instance for all the requests (minimum - maximum).</p>
  <blockquote>
  <p>WebClient sync: 8 ms - 167 ms <br />
  HttpClient sync: 3 ms - 7228 ms <br />
  HttpClient async: 985 - 10405 ms</p>
  </blockquote>
  <p>Using a new <code>HttpClient</code> for each request (minimum - maximum):</p>
  <blockquote>
  <p>WebClient sync: 4 ms - 297 ms <br />
  HttpClient sync: 3 ms - 7953 ms <br />
  HttpClient async: 1027 - 10834 ms</p>
  </blockquote>
  <h2>Code</h2>
  <pre class="lang-cs prettyprint-override"><code>public class AHNData
  {
      public int i;
      public string str;
  }
  
  public class Program
  {
      public static HttpClient httpClient = new HttpClient();
      private static readonly string _url = &quot;http://localhost:9000/api/values/&quot;;
  
      public static void Main(string[] args)
      {
         #region &quot;Trace&quot;
         Trace.Listeners.Clear();
  
         TextWriterTraceListener twtl = new TextWriterTraceListener(
             &quot;C:\\Temp\\REST_Test.txt&quot;);
         twtl.Name = &quot;TextLogger&quot;;
         twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;
  
         ConsoleTraceListener ctl = new ConsoleTraceListener(false);
         ctl.TraceOutputOptions = TraceOptions.DateTime;
  
         Trace.Listeners.Add(twtl);
         Trace.Listeners.Add(ctl);
         Trace.AutoFlush = true;
         #endregion
  
         int batchSize = 1000;
  
         ParallelOptions parallelOptions = new ParallelOptions();
         parallelOptions.MaxDegreeOfParallelism = batchSize;
  
         ServicePointManager.DefaultConnectionLimit = 1000000;
  
         Parallel.For(0, batchSize, parallelOptions,
             j =&gt;
             {
                 Stopwatch sw1 = Stopwatch.StartNew();
                 GetDataFromHttpClientAsync&lt;List&lt;AHNData&gt;&gt;(sw1);
             });
         Parallel.For(0, batchSize, parallelOptions,
              j =&gt;
              {
                  Stopwatch sw1 = Stopwatch.StartNew();
                  GetDataFromHttpClientSync&lt;List&lt;AHNData&gt;&gt;(sw1);
              });
         Parallel.For(0, batchSize, parallelOptions,
              j =&gt;
              {
                  using (WebClient client = new WebClient())
                  {
                     Stopwatch sw = Stopwatch.StartNew();
                     byte[] arr = client.DownloadData(_url);
                     sw.Stop();
  
                     Trace.WriteLine(&quot;WebClient Sync &quot; + sw.ElapsedMilliseconds);
                  }
             });
  
             Console.Read();
          }
  
          public static T GetDataFromWebClient&lt;T&gt;()
          {
              using (var webClient = new WebClient())
              {
                  webClient.BaseAddress = _url;
                  return JsonConvert.DeserializeObject&lt;T&gt;(
                      webClient.DownloadString(_url));
              }
          }
  
          public static void GetDataFromHttpClientSync&lt;T&gt;(Stopwatch sw)
          {
              HttpClient httpClient = new HttpClient();
              var response = httpClient.GetAsync(_url).Result;
              var obj = JsonConvert.DeserializeObject&lt;T&gt;(
                  response.Content.ReadAsStringAsync().Result);
              sw.Stop();
  
              Trace.WriteLine(&quot;HttpClient Sync &quot; + sw.ElapsedMilliseconds);
          }
  
          public static void GetDataFromHttpClientAsync&lt;T&gt;(Stopwatch sw)
          {
             HttpClient httpClient = new HttpClient();
             var response = httpClient.GetAsync(_url).ContinueWith(
                (a) =&gt; {
                   JsonConvert.DeserializeObject&lt;T&gt;(
                      a.Result.Content.ReadAsStringAsync().Result);
                   sw.Stop();
                   Trace.WriteLine(&quot;HttpClient Async &quot; + sw.ElapsedMilliseconds);
                }, TaskContinuationOptions.None);
          }
      }
  }
  </code></pre>
  <h2>My Questions</h2>
  <ol>
  <li>The REST calls return in 3-4 seconds which is acceptable.  Calls to REST
  service are initiated in the controller methods which gets invoked from
  Ajax calls. To begin with, the calls runs in a different thread and doesn't block the UI. So, can I just stick with synchronous calls?</li>
  <li>The above code was run in my localbox. In a production setup, DNS and proxy
  lookup will be involved. Is there an advantage of using <code>HttpClient</code> over <code>WebClient</code>?</li>
  <li>Is <code>HttpClient</code> concurrency better than <code>WebClient</code>? From the test results, I see <code>WebClient</code> synchronous calls perform better.</li>
  <li>Will <code>HttpClient</code> be a better design choice if we upgrade to .NET 4.5? Performance is the key design factor.</li>
  </ol>