title: C# HttpClient; How to make safe async calls?
body: <p>I have a site that exercises a third party API.  This API will tell me the values of accounts for a user.  The API has become unresponsive, and this has highlighted a flaw in my code.  I am getting the exception "Thread was being aborted." in the try-catch trap around the call, and in EventViewer I can see the HttpException RequestTimedOut.</p>
  
  <p>I am trying to use HttpClient, in a synchronous manner.  This works fine when the API is responsive, but it is coming apart now that the API is very slow to respond.</p>
  
  <p>I have an overview page that tries to gather all the account values for all users.
  There are 3 types of users (CLIENT, LIAISON, MEMBER).  The page makes three asynchronous Javascript calls for each type of account.  The fact that there are three calls made is (most probably) a red-herring, but I am declaring it to be safe.</p>
  
  <p>The server takes each call, gets the users for each call.  So, for the CLIENT call, the system pulls up the all the CLIENT users, and serially steps through them.  It makes an HTTP request per CLIENT user to get the account value.</p>
  
  <p>Each call has a new HttpClient object created for it, wrapped in a using statement.</p>
  
  <p>I strongly suspect that IIS is spotting the idle thread and shutting it down, which is fair enough.</p>
  
  <p>How can I make the API call so that I return the thread to the pool until I get a response?</p>
  
  <pre><code>    private static string getTotalAssets(string blockChainAddress, string identity)
      {
          var prefix = "getTotalAssets() - ";
          string msg = "";
  
          using (var handler = new HttpClientHandler { UseCookies = false, PreAuthenticate = true })
          using (var client = new HttpClient(handler))
          {
              // Timeout
              TimeSpan tsTimeout = new TimeSpan(0, 0, 0, _timeout);
              client.Timeout = tsTimeout;
  
              var message = new HttpRequestMessage(HttpMethod.Post, _urlSettleAPIGetTotalAssets);
  
              // Accept Json
              message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MIME_JSON));
  
              // Form the content to send
              string content = getTotalAssetsContent(blockChainAddress);
  
              // Add to the message
              message.Content = new StringContent(content);
  
              // Make API Call
              string sCallRef = "GET TOTAL ASSETS FOR [" + identity + "]";
              Tuple&lt;HttpResponseMessage, string&gt; result = MakeAPICall(client, message, content, sCallRef);
              if (result.Item1 == null)
                  return result.Item2; // Error during call
  
              // Call returned
              HttpResponseMessage response = result.Item1;
              string responseString = result.Item2;
  
              if (!response.IsSuccessStatusCode)
              {
                  msg = "Response Status Code: " + response.StatusCode.ToString();
                  logger.Debug(prefix + msg);
                  return "Error [" + result.Item2 + "]; " + msg;
              }
  
              // Else, call returned 200-OK
  
              logger.Debug(prefix + "Response:\r\n" + responseString + "\r\n");
  
              return processGetTotalAssetsResponseString(responseString);
  
          } // end of using...
      }
  
  
  
      public static Tuple&lt;HttpResponseMessage, string&gt; MakeAPICall(HttpClient client, HttpRequestMessage message, string content, string callRef)
      {
          var prefix = "MakeAPICall() - ";
          string msg = "";
  
          HttpResponseMessage responseMessage;
          string responseString = "";
          try
          {
              responseMessage = client.SendAsync(message).GetAwaiter().GetResult();
              responseString = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
  
              return new Tuple&lt;HttpResponseMessage, string&gt;(responseMessage, responseString);
          }
          catch (Exception ex)
          {
              msg = "Exception during call; \r\nBaseMessage:[" + ex.GetBaseException().Message + "]; \r\nMessage:[" + ex.Message + "]";
              logger.Warn(prefix + msg);
  
              return new Tuple&lt;HttpResponseMessage, string&gt;(null, msg);
          }
  
      } // end of MakeAPICall()
  </code></pre>