为啥缓存 WCF 通道是一件坏事?
Posted
技术标签:
【中文标题】为啥缓存 WCF 通道是一件坏事?【英文标题】:Why is caching WCF channels a bad thing?为什么缓存 WCF 通道是一件坏事? 【发布时间】:2011-09-05 20:01:45 【问题描述】:我在网上阅读了很多 WCF 文章,似乎大多数人缓存 ChannelFactory 对象而不是通道本身。似乎大多数人都害怕使用通道缓存,因为他们不想处理可能导致缓存通道不可用的网络故障。但这可以通过在方法上捕获 CommunicationException、重新创建通道并使用反射重播方法来轻松解决。
然后有些人认为进行通道缓存很糟糕,因为所有通信都将通过单个通道进行。请参阅以下文章。
http://social.msdn.microsoft.com/Forums/is/wcf/thread/9cbdf92a-a749-40ce-9ebe-3f2622cd78ee
这一定是件坏事吗?你不能跨线程共享频道吗?由于对这个单一通道的多个方法调用将被串行处理,性能会受到影响吗?
我没有发现共享频道会降低性能的证据。我确实发现使用缓存通道比使用非缓存通道快 5 倍,即使这意味着必须使用反射对缓存通道进行方法调用。
另一个优点是,当您完成所有 WCF 调用时,不必使用 try/catch/finally 语句在通道上调用 Close()、Abort() 或 Dispose()。在我看来,WCF 似乎朝着错误的方向迈出了一步,迫使开发人员必须管理 WCF 通道资源。在 .NET Remoting 中,您使用 Activator 类创建了代理,您无需对它执行任何操作即可对其进行清理。 .NET Framework 为您处理了所有这些。
【问题讨论】:
这是个好问题。 【参考方案1】:2 个主要原因:
-
ChannelFactory 的创建成本很高,而且它是线程安全的 => 非常适合缓存。
由通道工厂生成的通道创建起来并不昂贵,但它不是线程安全的(实际上它是线程安全的,但并发调用将被阻塞并按顺序执行)=> 不要在多线程环境中缓存它.
这是一个nice article,其中包含更多详细信息。
【讨论】:
@Tom C. 这是一个nice article,其中包含更多详细信息。根据它,通道确实是线程安全的,但会阻止并发访问并按顺序执行。 根据使用的 WCF 选项,通道可以包含特定于某个会话的状态。所以最好的建议肯定是:缓存工厂,而不是通道。 是的,我同意同一通道上的并发调用将按顺序执行,在多线程环境中可能会出现问题。但这可以通过通道池来解决。创建通道可能不像创建 ChannelFactory 那样昂贵,但它仍然有成本。而且这种成本会随着时间的推移而增加,对于一些高性能系统来说是不可接受的。 也许微软认为大多数软件系统可以在没有缓存通道的性能提升的情况下生存,但这仍然不能解释为什么微软强迫开发人员控制通道清理。为什么让开发人员必须将他们的 to 代理转换为 IClientChannel,以便开发人员可以确定是否在通道上调用 Close()/Abort()/Dispose()。当通道超出范围时,为什么不能作为垃圾收集的一部分自动完成。以上是关于为啥缓存 WCF 通道是一件坏事?的主要内容,如果未能解决你的问题,请参考以下文章
WCF ChannelFactory 和通道 - 缓存、重用、关闭和恢复