在存储库上Ninject WCF垃圾收集 [英] Ninject WCF Garbage Collection on repositories

查看:211
本文介绍了在存储库上Ninject WCF垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Ninject 2.2和WCF扩展。在我的大部分服务中,存储库都很快实例化/发布。但是,我的一项服务执行长时间运行(2-3分钟)。如果我看w3wp进程,我可以看到使用SQL建立的TCP / IP连接,我可以在SQL上运行sp_who2并查看连接。



当这些操作完成时,连接保持开放5-10分钟。

当我多次运行该操作时,没有看到新的连接正在生成,但是我将有多个应用程序正在运行,而之前我看到性能下降,同时发送了长时间运行的操作,并在几分钟后自行修复。

这个垃圾收集可能是问题的一部分如何解决这个问题?



这是我的Ninject绑定:

 绑定< ISomeRepository>()到< SomeRepository>()InRequestScope(); 

这是我的WCF绑定:

 < binding name =xxxcloseTimeout =00:01:00
openTimeout =00:01:00receiveTimeout =00:10:00sendTimeout = 00:10:00
bypassProxyOnLocal =falsetransactionFlow =false
hostNameComparisonMode =StrongWildcardmaxBufferPoolSize =524288
maxReceivedMessageSize =99999999messageEncoding =Text
textEncoding =utf-8useDefaultWebProxy =falseallowCookies =false>
< readerQuotas maxDepth =90maxStringContentLength =99999
maxArrayLength =99999999maxBytesPerRead =4096
maxNameTableCharCount =16384/>
< reliableSession ordered =trueinactivityTimeout =00:10:00
enabled =true/>
< security mode =.../>
< / binding>

< service name =SomeService
behaviorConfiguration =abcd>
< endpoint name =BasicEndPointaddress =http://localhost/SomeService.svc
binding =wsHttpBindingbindingConfiguration =xxx
contract =ISomeJobService/> ;
< / service>

我意识到一种选择是将服务使用的存储库数量减少到一个,但是我我真的正在寻找一个临时解决方案。

解决方案

InRequestScope 函数在WCF中除非 IIS兼容模式。这不是默认模式,也不推荐用于大多数目的。



当您尝试这样做时,实际发生的事情是Ninject将使用 null 作用域,这相当于根本不指定任何作用域。这反过来导致标准缓存和收集行为,这意味着Ninject会在它感觉到它时抛弃这些连接(从而将它们释放回连接池),以表明它非常简单的条款。

在WCF中最类似于​​这个的是 OperationScope 。你可以绑定使用

 绑定(...)。(...)。InScope(()=> OperationContext .Current)

这是一个半熟的解决方案,但我认为它现在应该可以正常工作,因为 NinjectServiceHostFactory 会添加一个服务行为,在请求(即操作)结束时自动通知缓存。



最近在官方扩展中添加了这种支持,我想最近在2011年3月份,所以请确保您使用的是最新版本。在撰写本文时,这是2.3.0.0。


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.

这篇关于在存储库上Ninject WCF垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆