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>