title: HttpContent.ReadAsStringAsync causes request to hang (or other strange behaviours)
body: <p>We are building a highly concurrent web application, and recently we have started using asynchronous programming extensively (using TPL and <code>async</code>/<code>await</code>).</p>
  
  <p>We have a distributed environment, in which apps communicate with each other through REST APIs (built on top of ASP.NET Web API). In one specific app, we have a <code>DelegatingHandler</code> that after calling <code>base.SendAsync</code> (i.e., after calculating the response) logs the response to a file. We include the response's basic information in the log (status code, headers and content):</p>
  
  <pre class="lang-cs prettyprint-override"><code>public static string SerializeResponse(HttpResponseMessage response)
  {
      var builder = new StringBuilder();
      var content = ReadContentAsString(response.Content);
  
      builder.AppendFormat("HTTP/{0} {1:d} {1}", response.Version.ToString(2), response.StatusCode);
      builder.AppendLine();
      builder.Append(response.Headers);
  
      if (!string.IsNullOrWhiteSpace(content))
      {
          builder.Append(response.Content.Headers);
  
          builder.AppendLine();
          builder.AppendLine(Beautified(content));
      }
  
      return builder.ToString();
  }
  
  private static string ReadContentAsString(HttpContent content)
  {
      return content == null ? null : content.ReadAsStringAsync().Result;
  }
  </code></pre>
  
  <p>The problem is this: when the code reaches <code>content.ReadAsStringAsync().Result</code> under heavy server load, the request sometimes hangs on IIS. When it does, it sometimes returns a response -- but hangs on IIS as if it didn't -- or in other times it never returns.</p>
  
  <p>I have also tried reading the content using <code>ReadAsByteArrayAsync</code> and then converting it to <code>String</code>, with no luck.</p>
  
  <p>When I convert the code to use async throughout I get even weirder results:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public static async Task&lt;string&gt; SerializeResponseAsync(HttpResponseMessage response)
  {
      var builder = new StringBuilder();
      var content = await ReadContentAsStringAsync(response.Content);
  
      builder.AppendFormat("HTTP/{0} {1:d} {1}", response.Version.ToString(2), response.StatusCode);
      builder.AppendLine();
      builder.Append(response.Headers);
  
      if (!string.IsNullOrWhiteSpace(content))
      {
          builder.Append(response.Content.Headers);
  
          builder.AppendLine();
          builder.AppendLine(Beautified(content));
      }
  
      return builder.ToString();
  }
  
  private static Task&lt;string&gt; ReadContentAsStringAsync(HttpContent content)
  {
      return content == null ? Task.FromResult&lt;string&gt;(null) : content.ReadAsStringAsync();
  }
  </code></pre>
  
  <p>Now <code>HttpContext.Current</code> is null after the call to <code>content.ReadAsStringAsync()</code>, and <strong>it keeps being null for all the subsequent requests</strong>! I know this sounds unbelievable -- and it took me some time and the presence of three coworkers to accept that this was really happening.</p>
  
  <p>Is this some kind of expected behavior? Am I doing something wrong here?</p>