title: Most efficient configuration of C# Tasks and Continuations when calling a web service?
body: <p>I am creating a network client that talks to a real-time web API. </p>
  
  <p>The client must make many different calls per second and feed a <code>Task&lt;TResult&gt;</code> back to each client component so the client can decide whether to block:</p>
  
  <pre><code>public Task&lt;TResult&gt; Execute&lt;TResult&gt;(IOperation&lt;TResult&gt; operation);
  </code></pre>
  
  <p>The process of making an API call runs like this:</p>
  
  <ol>
  <li>Serialize the (small, less than 1KB) request to Json</li>
  <li>Send the request using an <code>HttpClient</code></li>
  <li>On success, deserialize to <code>TResult</code> (Json could be a few hundred KB in size, but usually much smaller) and return</li>
  </ol>
  
  <p>In my tests, choosing where to include each step within a Task workflow (and therefore on which thread) has a significant impact on the performance.</p>
  
  <p>The fastest setup I have found so far is this (semi-pseudo-code, omitted generic type params for brevity):</p>
  
  <pre><code>// serialize on main thread
  var requestString = JsonConvert.SerializeObject(request);
  // create message - omitted
  var post = Task.Factory.StartNew(() =&gt; this.client.SendAsync(requestMessage)).Unwrap();
  return post.ContinueWith(response =&gt;
              {
                  var jsonString = response.Result.Content.ReadAsStringAsync();
                  return JsonConvert.DeserializeObject(jsonString.Result);
              });
  </code></pre>
  
  <p>The slowest is this setup where the whole process is executed within a single task:</p>
  
  <pre><code>return Task.Factory.StartNew((request) =&gt; 
              {
                  var requestString = JsonConvert.SerializeObject(request);
                  // create message - omitted
                  var post = client.SendAsync(requestMessage);
                  var jsonString = post.Result.Content.ReadAsStringAsync();
                  return JsonConvert.DeserializeObject(jsonString.Result);
              })
  </code></pre>
  
  <p>I would have thought the last method could be quickest because you create one background thread per request. My assumption is that this doesn't allow the TPL to make the most efficient use of the available threads because of the blocking call.</p>
  
  <p>So, is there a general rule around what should go in a task and what should sit outside it, or in a continuation?</p>
  
  <p>In this specific case, are there any further optimisations I could try?</p>