1

I have around 10-20 tasks that each perform a separate job. At some point during this job each task will eventually call the same WCF endpoint asynchronously to get data.

The WCF endpoint does exist on a server farm cluster of 8 servers. Within this endpoint there are multiple things happening (Stored Procedure calls, Data Calculation, SQL inserts, delete, updates) It sounds like a lot but One single call takes less than 1 second to return.

The problem is running full throttle, the service starts queuing up the calls and the response times grow larger and larger and eventually timeout. Each has to be processed sequentially as the ProcessJob Webservice needs to insert the data into the database as soon as it can.

How can I prevent this queuing and timeout from happening?

   private void StartAllJobs()
   {
        List<Task> task = new List<Task>();
           foreach(job in JobList)
        {
          //Start the job on its own thread
         task.Add(Task.Run(await () => RunMyJob(job)));
        }
        Task.WaitAll(task.ToArray());
    }

    private async Task<string> RunMyJob(Job job)
    {
        //Other processing below
           var infoList = ProcessOtherStuff(job);
    
        using(var proxy=new serviceclient())
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
           for(var i=0;i<infoList.Count;i++)


     //The count can reach up to 20000 records to process
               {
                    try 
                    {
                     var value = await proxy.ProcessJob(info);
                         sw.Stop();
                         Console.Writeline("Process took this long:{0}", sw.Elapsed);
                     }
                  catch(Exception ex)
                   {
                    Console.Writeline("Exception {0}: Time:{1}, ex.Message, DateTime.Now.ToString());
                    }       
    
                  }
                   return "Complete";
                 }
                }

The error message is something like this

System.TimeoutException: The request channel timed out while waiting for a reply after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://localhost/ReportServer/ReportExecution2005.asmx' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. ---> System.Net.WebException: The operation has timed out

here is the client WCF config (only part that is related to the reporting services, not the entire WCF config)

<bindings>
  <wsHttpBinding>
    <binding name="ReportExecutionServiceSoap" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
        maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Non" proxyCredentialType="None"
          realm="" />           
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="https://serverfarm.com/MyServer/MyWebService.svc"
    binding="wsHttpBinding" bindingConfiguration="ReportExecutionServiceSoap"
    contract="ReportExecutionServiceReference.ReportExecutionServiceSoap"
    name="ReportExecutionServiceSoap" />
</client>

Then my service has

<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyBinding" contract="MyWebService.IMyWebService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
 <serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentInstances="70424" maxConcurrentCalls="10024" maxConcurrentSessions="60400" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpeBinding>
<binding name="MyBinding">
<readerQuotas 
maxArrayLength="16384" maxBytesPerRead="4096" maxDepth="32" maxNameTableCharCount="16384" maxStringContentLength="102400"/>
<security mode="Transport">
<transportclientCredentialType="None"/>
<messageestablishSecurityContext="false"/>
</security>
</binding>
Terrance Jackson
  • 606
  • 3
  • 13
  • 40
  • The timeouts are not related to the client-side it seems. What you can do is for the client-side is turn that concurrent requests into sequential requests (Or you can limit the concurrency). If you have a chance optime the server code. – Eldar Jan 14 '22 at 20:24
  • I have also tried calling it synchronously without the await and it still ends up queuing I am guessing because i have multiple tasks still calling the same endpoint even if it is at different times – Terrance Jackson Jan 14 '22 at 20:33
  • Then think about synchronization. [SemaphoreSlim](https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=net-6.0) is your choice. – Georgy Tarasov Jan 14 '22 at 23:42
  • Probably because of maxconnection limit in web config. https://stackoverflow.com/a/9875238/17218587 – Lan Huang Jan 18 '22 at 09:57

0 Answers0