Ninject WCF Garbage Collection on repositories
I'm using Ninject 2.2 with the WCF extension. On most of my services the repositories are instantiated/released quickly. However, one of my services performs long-running operations (2-3 min). If I watch the w3wp process I can see the TCP/IP connections being established with SQL and I can run sp_who2 on SQL and see the connections.
When these operations are complete, the connections remain open for 5-10 minutes.
I don't see new connections being spawned when I run the operation multiple times but I will have multiple instances of the app running and I saw a performance degradation previously while spamming those long running operations and it fixed itself after several minutes.
Could this garbage collection be part of the problem and how can it be addressed?
Here is my Ninject binding:
Bind<ISomeRepository>().To<SomeRepository>().InRequestScope();
Here is my WCF binding:
<binding name="xxx" closeTimeout="开发者_如何转开发00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
maxReceivedMessageSize="99999999" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="false" allowCookies="false">
<readerQuotas maxDepth="90" maxStringContentLength="99999"
maxArrayLength="99999999" maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="true" />
<security mode="..."/>
</binding>
<service name="SomeService"
behaviorConfiguration="abcd">
<endpoint name="BasicEndPoint" address="http://localhost/SomeService.svc"
binding="wsHttpBinding" bindingConfiguration="xxx"
contract="ISomeJobService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
I realize one option is to reduce the number of repositories in use by the service down to one but I'm really looking for an interim solution.
InRequestScope
has no function in WCF unless you are hosting in IIS compatibility mode. That is not the default mode, nor is it recommended for most purposes.
What will actually happen when you try this is that Ninject will use a null
scope, which is equivalent to not specifying any scope at all. That in turn results in the standard cache and collect behaviour, which means Ninject will dispose of those connections (thus releasing them back into the connection pool) whenever it feels like it, to state it in very simplistic terms.
The closest analog to this in WCF is the OperationScope
. You can bind using
Bind(...).To(...).InScope(() => OperationContext.Current)
This used to be a half-baked solution but I think it should work properly now, because the NinjectServiceHostFactory
adds a service behaviour which automatically notifies the cache when the "request" (that is, the operation) is over.
This support was added to the official extension very recently, I think as recently as March '11, so make sure you're using the latest. At the time of writing, that's 2.3.0.0.
精彩评论