How can I ensure that a WCF service uses threads from a ThreadPool to process incoming messages?
At the moment simple method invocation like 'return null;' takes about 45 seconds while another requests are processing
Here is how I have annotated my service class:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public partial class MyService : IMyService {
...
}
But when I'm watching the process in task manager it seems to be using a constant number of threads. Even under load.
public ActionResult SelectDatabase(string param)
{
if (!String.IsNullOrEmpty(param))
{
try
{
MyServicece svc = new MyService();
Database[] dbsArray = svc.GetDatabases(param);
if (depsArray != null)
ViewData["depsArray"] = depsArray;
return View();
}
catch (Exception exc)
{
// log here
return ActionUnavailable();
}
}
Here is my service behavior:
<?xml version="1.0"?>
<configuration>
<runtime>
</runtime>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
<system.serviceModel>
<diagnostics performanceCounters="Default" />
<bindings>
<netTcpBinding>
<binding sendTimeout="00:02:00" receiveTimeout="00:02:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
<security mode="None">
</security>
</binding>
</netTcpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<behaviors>
<endpointBehaviors>
<behavior name="CrossDomainServiceBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyService.MyServiceBehavior">
<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" maxConcurrentSessions="100" />
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyService">
<endpoint address="MyService" binding="netTcpBinding" contract="AService.IAServ" isSystemEndpoint="false" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyServiceAdmin">
<endpoint address="MyServiceAdmin" binding="netTcpBinding" contract="MyService.IMyServiceAdmin" isSystemEndpoint="false" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Here is how I create service instance:
ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(String.Format("net.tcp://{0}/", _bindAddress)));
myserviceHost.Open();
Console.WriteLine(myserviceHost.BaseAddresses[0]);
InstanceContextMode and ConcurrencyMode are separate concepts but which have a level of interplay - I blogged about this in some depth a while back
WCF calls are processed on IO threadpool threads. Assuming you haven't done something like ConcurrencyMode.Single
, InstanceContextMode.Single
which will serialize every call into the service the threadpool manager will try to balance the number of threads to the rate of work.
If the number of concurrent requests can be serviced by 5 threads then that's how many it will use. You may be seeing that the threadpool can keep up with the rate of work with the number of threads you can see. You can quite happily use more threads than cores with effect because, as long as the threads are not purely CPU bound, the OS can gain throughput by switching threads onto the CPU when the previously running thread starts IO. If the CPU is completely max'd out then the heuristics of the threadpool manager will make it reticent to add more threads into the thread pool
However, there are another couple of potential issues:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With