title: Scaling webclient using threadpool
body: <p>I have to create mutiple web request to same URL using webclient. I spawn thread using thread pool QueueUserWorkItem. Code below show how I am spawning thread and posting using WebClient. I had to derive web client class to set Expect100Continue and Timeout property. </p>
  
  <p>When I run this code without Thread.Sleep (commented line in spawn thread code), I am getting response time over 1500 millisecond. Please check the logic to calculate response time in PostToURL method. But If I put 1 seconds sleep before spawning another thread, I am getting response time less than 300 milliseconds. I could not find reason why is that so different. Actually I need to bring this response time to 300 millisecond. This is test harness code that I am writing to test a service. Can you point why is different response time?</p>
  
  <p>Here is the code that spawns the thread</p>
  
  <pre><code>foreach (var nameValueCollection in requestCollections)
  {
      NameValueCollection collection = nameValueCollection;
      ThreadPool.QueueUserWorkItem(a =&gt; { if (collection != null) PostToURL    
      (collection); });
      //Thread.Sleep(TimeSpan.FromSeconds(1));
   }
  </code></pre>
  
  <p>Here is method that post to a URL </p>
  
  <pre><code>public void PostToURL(NameValueCollection collection)
      {
          DateTime requestStartDate = DateTime.Now;
          DateTime requestEndDate = DateTime.Now;
          string encodedResponse;
          try
          {
              using (var transportType2 = new DerivedWebClient())
              {
                  transportType2.Expect100Continue = false;
                  transportType2.Timeout = TimeSpan.FromMilliseconds(2000);
  
                  ServicePointManager.ServerCertificateValidationCallback =
                      new RemoteCertificateValidationCallback(delegate { return true; });
  
                  requestStartDate = DateTime.Now;
                  var responseArray = transportType2.UploadValues("http://xyz/Post.ashx?AccountName=myaccount",
                                                                  "POST", collection);
                  requestEndDate = DateTime.Now;
                  Console.WriteLine(requestEndDate.Subtract(requestStartDate).TotalMilliseconds);
  
                  encodedResponse = Encoding.ASCII.GetString(responseArray);
  
                  transportType2.Dispose();
              }
          }
          catch (Exception exception)
          {
              requestEndDate = DateTime.Now;
              encodedResponse = exception.ToString();
          }
  
          //Global variable to record request and response
          responses.Add(new ServiceResponse
          {
              ResponseInMs = (int) requestEndDate.Subtract(requestStartDate).TotalMilliseconds,
              StartTime = requestStartDate,
              EndTime = requestEndDate,
              Response = encodedResponse,
              Request = string.Join(";", collection.Cast&lt;string&gt;()
                          .Select(col =&gt; String.Concat(col, "=", collection[col])).ToArray()),
              ApplicationId = collection["ApplicationId"]
  
          });
      }
  </code></pre>
  
  <p><strong>UPDATED</strong>
  Here is code that derive webclient </p>
  
  <pre><code>public class DerivedWebClient: WebClient
  {
      public bool Expect100Continue
      {
          get;
          set;
      }
  
      public TimeSpan Timeout
      {
          get;
          set;
      }
  
      protected override WebRequest GetWebRequest(Uri address)
      {
          var request = (HttpWebRequest)base.GetWebRequest(address);
          if (request != null)
          {
              request.ServicePoint.Expect100Continue = Expect100Continue;
              request.KeepAlive = false;
              request.Timeout = (int) Timeout.TotalMilliseconds;
          }
  
          return request;
      }
  }
  </code></pre>