title: why is my WCF server so slow
body: <p>I have created a WCF server and a WCF client to consume the service.
  The purpose of the server is to add 2 numbers being passed in and wait X milliseconds before returning the sum.</p>
  
  <p>The client creates Y tasks and starts them. Each task is a request for the server to add numbers and wait the X milliseconds.</p>
  
  <p>When x = 0 and y = 1000 it takes an average of 6.2 Seconds to complete all tasks.
  When X = 0 and Y = 10000 it takes an average of 61 Seconds to complete all tasks.</p>
  
  <p>Why is it so slow or maybe this is normal?</p>
  
  <p>thanks
  Damo</p>
  
  <p><strong>Client C# methods</strong></p>
  
  <pre><code>private void radButtonTaskWithStatus_Click(object sender, EventArgs e)
          {
              try
              {
                  var dateTime1 = DateTime.UtcNow;
                  radProgressBarStatus.Maximum = int.Parse(radTextBoxFloodRequests.Text);
                  radProgressBarStatus.Value1 = 0;
  
                  Random rnd = new Random();
  
  
                  Task&lt;int&gt;[] tasks = new Task&lt;int&gt;[int.Parse(radTextBoxFloodRequests.Text)];
  
                  for (int i = 0; i &lt; int.Parse(radTextBoxFloodRequests.Text); i++)
                  {
                      int x = i;
                      tasks[i] = new Task&lt;int&gt;(() =&gt;
                      {    
  
                          int FirstRandomNumber = rnd.Next(1, 20);
                          int SecondRandomNumber = rnd.Next(1, 20);
  
  
                          int result = TaskRequestWithResult(FirstRandomNumber, SecondRandomNumber, int.Parse(radTextBoxFloodDelay.Text), x);    
  
                          return result;
                      });
                  }
  
                  var continuation = Task.Factory.ContinueWhenAll(
                              tasks,
                              (antecedents) =&gt;
                              {
                                  var dateTime2 = DateTime.UtcNow;
                                  var diffInSeconds = (dateTime2 - dateTime1).TotalSeconds;
                                  this.radListView1.BeginInvoke((MethodInvoker)(() =&gt; this.radListView1.Items.Add((dateTime2 - dateTime1).TotalSeconds)));
                                  //MessageBox.Show(diffInSeconds.ToString());
  
  
                                  int total = 0;
                                  for (int i = 0; i &lt; int.Parse(radTextBoxFloodRequests.Text); i++)
                                      total = total + tasks[i].Result;
                                  Debug.Print("Finished - Sum of all results is: " + total);
                                  //RadMessageBox.Show("Finished - Sum of all results is: " + total);                     
                              });
  
  
                  for (int i = 0; i &lt; int.Parse(radTextBoxFloodRequests.Text); i++)
                  {
                      tasks[i].Start();
                    //  System.Threading.Thread.Sleep(10); // Wait
                  }
  
                  TaskProgress(tasks, count =&gt; Invoke(new MethodInvoker(() =&gt; radProgressBarStatus.Value1 = count)));
  
                  // Use next line if you want to block the main thread until all the tasks are complete
                  //continuation.Wait();
  
  
              }
              catch (Exception ex)
              {
  
                  MessageBox.Show(ex.Message.ToString());
  
              }
          }
  
          public static void TaskProgress(IEnumerable&lt;Task&gt; tasks, Action&lt;int&gt; callback)
          {
              int count = 0;
              foreach (var task in tasks)
                  task.ContinueWith(t =&gt; callback(Interlocked.Increment(ref count)));
          }
  
          private int TaskRequestWithResult(int number1, int number2, int delay, int count)
          {
  
              try
              {
  
                  ServiceReference1.WCFJobsLibraryClient Client = new ServiceReference1.WCFJobsLibraryClient();
                  Client.Endpoint.Address = new System.ServiceModel.EndpointAddress(radTextBoxbaseAddress.Text);
                  WCFClient.ServiceReference1.ReturnClass AddNumbers_Result;
  
                  AddNumbers_Result = Client.AddNumbers(number1, number2, delay);
  
  
                  if (AddNumbers_Result.ErrorCode &lt; 0)
                  {
                      // If exception happens, it will be returned here
                      MessageBox.Show(AddNumbers_Result.ErrorCode.ToString() + " " + AddNumbers_Result.ErrorMessage + " " + AddNumbers_Result.ExMessage);
                  }
  
                  else
                  {
                      Debug.Print("Task Executing now: " + count.ToString());                   
  
                  }
  
                  return AddNumbers_Result.Result;
  
              }
  
              catch (Exception ex)
              {                
                  MessageBox.Show(ex.Message.ToString());
                  return -1;
  
              }
          }
  
  
      }
  </code></pre>
  
  <p><strong>Client App.config</strong></p>
  
  <pre><code>&lt;configuration&gt;
      &lt;system.serviceModel&gt;
          &lt;bindings&gt;
              &lt;basicHttpBinding&gt;
                  &lt;binding name="BasicHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
                      receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false"
                      bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                      maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                      useDefaultWebProxy="true"&gt;
                      &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                          maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;
                      &lt;security mode="None"&gt;
                          &lt;transport clientCredentialType="None" proxyCredentialType="None"
                              realm="" /&gt;
                          &lt;message clientCredentialType="UserName" algorithmSuite="Default" /&gt;
                      &lt;/security&gt;
                  &lt;/binding&gt;
              &lt;/basicHttpBinding&gt;
          &lt;/bindings&gt;
          &lt;client&gt;
              &lt;endpoint address="http://localhost:8732/Design_Time_Addresses/WCFService/WCFJobsLibrary/"
                  binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint"
                  contract="ServiceReference1.IWCFJobsLibrary" name="BasicHttpEndpoint" /&gt;
          &lt;/client&gt;
      &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p><strong>Server C# methods</strong></p>
  
  <pre><code>[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
  public class WCFJobsLibrary : IWCFJobsLibrary
  {
  
      public ReturnClass AddNumbers(int FirstNumber, int SecondNumber, int Delay) //Add two numbers and wait a predefined interval
      {
          Logging.Write_To_Log_File("Entry", MethodBase.GetCurrentMethod().Name, "", "", "", 1);
          ReturnClass myReturnClass = new ReturnClass(-1, null, null, 0);
          try
          {             
  
              myReturnClass.ErrorCode = 1;
  
              myReturnClass.Result = FirstNumber + SecondNumber;
  
              System.Threading.Thread.Sleep(Delay); // Wait
              Logging.Write_To_Log_File("Exit", MethodBase.GetCurrentMethod().Name, "", "", "", 1);
              return myReturnClass;
  
          }
          catch (Exception ex)
          {
              Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), 2);
              myReturnClass.ErrorCode = -1;
              myReturnClass.ErrorMessage = ex.ToString();
              return myReturnClass;
          }
  
      }
  
  //Add two numbers and wait defined interval
  [OperationContract]
  ReturnClass AddNumbers(int FirstNumber, int SecondNumber, int Delay);
  </code></pre>
  
  <p><strong>Server App.config</strong></p>
  
  <pre><code>&lt;configuration&gt;
    &lt;system.serviceModel&gt;
    &lt;services&gt;
      &lt;service name="WCFService.WCFJobsLibrary" behaviorConfiguration="Throttled" &gt;
        &lt;endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
          name="BasicHttpEndpoint" contract="WCFService.IWCFJobsLibrary"&gt;
          &lt;identity&gt;
            &lt;dns value="localhost" /&gt;
          &lt;/identity&gt;
        &lt;/endpoint&gt;
        &lt;endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /&gt;
        &lt;host&gt;
          &lt;baseAddresses&gt;
            &lt;add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFService/WCFJobsLibrary/" /&gt;
          &lt;/baseAddresses&gt;
        &lt;/host&gt;
      &lt;/service&gt;
    &lt;/services&gt;
    &lt;behaviors&gt;
      &lt;serviceBehaviors&gt;
        &lt;behavior name="Throttled"&gt;
          &lt;!-- To avoid disclosing metadata information, 
            set the value below to false and remove the metadata endpoint above before deployment --&gt;
          &lt;serviceMetadata httpGetEnabled="true" /&gt;
          &lt;!-- To receive exception details in faults for debugging purposes, 
            set the value below to true.  Set to false before deployment 
            to avoid disclosing exception information --&gt;
          &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt;
          &lt;serviceThrottling maxConcurrentCalls="100000" maxConcurrentInstances="100000" maxConcurrentSessions="100000" /&gt;
        &lt;/behavior&gt;
      &lt;/serviceBehaviors&gt;
    &lt;/behaviors&gt;
    &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>