Autofac解析的WCF客户端导致Web API应用程序

时间:2016-11-23 10:35:01

标签: c# .net wcf asp.net-web-api autofac

我在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对象层次结构:screen(对于照片感到抱歉,工作时禁止截图上传)。 / p>

所以现在我不知道如何解决这个问题。也许我做错了什么。或者也许有人遇到过同样的问题。欢迎任何建议。

1 个答案:

答案 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我说这有两个原因:

  1. 如果您的控制器具有需要服务代理的操作,则会阻止其主动实例化。如果需要代理,请调用自动注入的工厂函数。如果没有,不用担心 - 并且没有额外的内存使用。
  2. 如果您的服务代理对通道造成错误,您无法再次使用它......如果没有工厂功能,则无法让自己成为新手。如果你只是为每个控制器动作拨打一个服务电话,那就没什么大不了了,但是如果你想允许重试,打电话给多个等等,你就会想要那个工厂。
  3. 那很长,它可能无法解决问题,但我希望它有所帮助。