Reputation: 1
I'm having a unclear CPU issue with WCF services using NetTcp binding (hosted on IIS 8 on Windows Server 2012 Datacenter) I'm holding WCF clients (proxies) pool in one service and use it to connect the other.. Our problem is that when the client service that holds the pool is not properly disposed (which is possible scenario for us) then the server is spinning up to 100% CPU and stay there for while ( the duration is strongly depends on the number of the clients in the pool which haven’t been closed) We are using InstanceContextMode.Single with multiple concurrency mode on the server and no reliable sessions..
server configuration:
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IRecommenderService" closeTimeout="00:00:01.5000000" openTimeout="00:00:01.5000000" receiveTimeout="00:00:01.5000000" sendTimeout="00:00:01.5000000" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" listenBacklog="2147483647" transactionFlow="false">
<readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
<reliableSession enabled="false"/>
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceThrottling maxConcurrentCalls="4000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
</behavior>
<behavior name="Unthrottled">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceThrottling maxConcurrentCalls="6000" maxConcurrentSessions="6000" maxConcurrentInstances="6000" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="UnthrottledServiceEndpoint">
<dispatcherSynchronization maxPendingReceives="10000" asynchronousSendEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
Client configuration:
<client>
<endpoint address="net.tcp://this-will-be-given-at-runtime:12345/an-invalid-service-too/"
behaviorConfiguration="UnthrottledClientEndpoint" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IRecommenderService" contract="RecommenderClient.IRecommenderService"
name="IRecommenderServiceClient_nettcp" />
</client>
...
<behavior name="UnthrottledClientEndpoint">
<dispatcherSynchronization asynchronousSendEnabled="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
...
Any answer will be appreciated Thanks, Sagi.
Upvotes: 0
Views: 673
Reputation: 27842
//when the client service that holds the pool is not properly disposed (which is possible scenario for us) //
Are you saying you wrote your own "pool" for WCF connections?
I wouldn't do that. I would use the proxy and dispose of it after each use....to avoid the exact thing you're describing.
If you cannot "trust" your dotnet consumers to close/dispose of things, then I would suggest (as I do) to write a ClientWrapper assembly, and they must go through it...and YOU make sure you close the proxies.
I liken it to an IDataReader. If I returned IDataReaders to the client, I cannot guarantee the consumer disposes of them. Aka, it is outside of my control. No way. I consume the IDataReader, dispose of it, and give them back some (serialized?) object. The consumer would never get something back that they could forget to dispose of, and screw me me.
Below is my typical "client side" wrapper code.
private IMyService GetTheProxy()
{
string endPointName = "MyEndPointName";
ChannelFactory<IMyService> factory;
//Use default endpoint
Console.WriteLine("endPointName='{0}'", endPointName);
factory = new ChannelFactory<IMyService>(endPointName);
IMyService proxy1 = factory.CreateChannel();
return proxy1;
}
public string GetAString()
{
string returnValue = null;
IMyService proxy1 = this.GetTheProxy();
using (proxy1 as IDisposable)
{
returnValue = proxy1.GetAString();
return returnValue ;
}
}
public int GetAnInt()
{
int returnValue = null;
IMyService proxy1 = this.GetTheProxy();
using (proxy1 as IDisposable)
{
returnValue = proxy1.GetAnInt();
return returnValue ;
}
}
Upvotes: 1