我在ASP.NET Web API(2.2又名5.2.3)中遇到了问题。我还使用Autofac 4.2.0,Autofac.Wcf 4.0.0和Autofac.WebApi2 4.0.1。 WCF服务依赖项以这种方式配置(与docs中相同):
builder.Register(c => new ChannelFactory<ISchedulerWcfService>
("SchedulerService"))
.SingleInstance();
builder.Register(c => c.Resolve<ChannelFactory<ISchedulerWcfService>>
().CreateChannel())
.As<ISchedulerWcfService>
()
.UseWcfSafeRelease();
在Web.config中:
<ISchedulerWcfService>
然后使用标准构造函数注入消耗服务。 我假设使用UseWcfSafeRelease()扩展方法使Autofac正确处理服务代理。但实际上,当我分析应用程序时,在使用WCF服务的合理数量的Web API请求之后,我获得了数千个ServiceChannel对象层次结构:(对于照片感到抱歉,工作时禁止截图上传)。 / p>
所以现在我不知道如何解决这个问题。也许我做错了什么。或者也许有人遇到过同样的问题。欢迎任何建议。
答案 0 :(得分:1)
这可能看起来像评论,但它有点长的评论,或者至少是一些漫无边际的指示。坚持我。
看起来您的WCF客户端内容已正确连接。不要担心该部分。看起来是正确的。
UseWcfSafeRelease
可以阻止频道关闭的例外情况。它会在频道上调用{em>而不是来调用IDisposable.Dispose
。其中的代码不多; it's probably better if you just look at it
所以,有一点保证/确认,到目前为止,这么好。
现在,关于泄漏,因为它......
这里还不足以确切地说明发生了什么。鉴于问题与您注册WCF客户端的方式不同,这意味着还有别的东西在继续。
左侧的堆栈看起来很正常。您将自下而上注意到它基本上是读取的,&#34;附加到Autofac依赖性解析器的HttpConfiguration的单个实例解析了一个单独的通道工厂,该工厂打开一个通道并保持它&#34;这很标准。你可以看到它是一个单身人士,因为&#34; rootLifetimeScope&#34;在跟踪中,事情正在被添加到&#34; sharedInstances&#34;字典,等等。
右边的堆栈是我正在努力寻找的东西。我猜测整个堆栈并没有显示在那里,因为我实际上并没有在该堆栈中的任何地方看到Autofac。但是,这是与你的控制器在一起的堆栈,这意味着可能是生成和保持各个通道的地方。当然,这也可能意味着您的控制器和整个对象堆栈被保留,这也应该出现在那里。
很高兴看到哪个堆栈中包含对象。这就是原因:
了解Autofac handles disposal我们如何知道使用OnRelease
处理程序的一次性对象或事物将被保留,直到处置了拥有的生命周期范围。这就是为什么{{ 3}}只要有可能 - 所以一次性用品在使用期限内不会被扣留。
... SOOOO
查找从容器中解析的应用程序级别的内容。例如,我发现经典的ASP.NET应用程序尝试使用{{1}中的服务位置从容器中解析}。那不好。我并不是说你正在做的事情,我说要注意并在应用程序中查看从应用程序容器中解决的问题。
这是Web API响应缓冲的问题吗? you should always resolve from a lifetime scope rather than the root container有人发现Web API和OWIN会长时间保留一些上下文内容 - 包括生命周期范围引用。 We saw a question recently我们正在进行更积极主动的清洁工作Based on that。
持有请求生命周期范围的东西太长了吗?例如......
HttpModule
太长了吗?在Web API中,请求生命周期范围与HttpRequestMessage
一起流动。如果请求消息没有被处理掉,那么生命周期范围就不会被处理掉,因此WCF代理不会被处置。HttpRequestMessage
请求的内容太长了?类似于上面关于ILifetimeScope
的说明,我已经看过了人们有时会在课程中注入HttpRequestMessage
,以便他们可以进行服务定位。这些是要寻找的东西。
最后,提示:
不要将ILifetimeScope
注入您的控制器,而应考虑ISchedulerWcfService
。我说这有两个原因:
那很长,它可能无法解决问题,但我希望它有所帮助。