问题 为什么缓存WCF频道是件坏事?


我一直在线阅读很多WCF文章,似乎大多数人都会缓存ChannelFactory对象而不是频道本身。看起来大多数人都害怕使用频道缓存,因为他们不想处理可能导致缓存频道无法使用的网络故障。但是,通过在方法上捕获CommunicationException,重新创建通道并使用Reflection重放方法,可以很容易地解决这个问题。

然后有人认为进行频道缓存是不好的,因为所有通信都将通过单一频道进行。见以下文章。

http://social.msdn.microsoft.com/Forums/is/wcf/thread/9cbdf92a-a749-40ce-9ebe-3f2622cd78ee

这一定是件坏事吗?你能跨线程共享频道吗?性能是否会受到影响,因为对此单个通道的多个方法调用将被串行处理?

我没有发现共享渠道会降低性能的证据。我所发现的是,使用缓存通道比使用非缓存通道快约5倍,即使这意味着必须使用Reflection在缓存通道上调用方法。

另一个优点是不必使用try / catch / finally语句包围所有WCF调用,以便在完成后调用通道上的Close(),Abort()或Dispose()。对我来说,似乎WCF通过强迫开发人员必须管理WCF信道资源而朝着错误的方向迈出了一步。在.NET Remoting中,您使用Activator类创建了代理,并且您无需执行任何操作来清理它。 .NET Framework为您处理了所有这些。


4029
2018-05-31 21:32


起源

这是一个很好的问题。 - Repo Man


答案:


2个主要原因:

  1. ChannelFactory创建起来很昂贵,并且它是线程安全=>完美的缓存候选者。
  2. 由通道工厂生成的通道创建起来并不昂贵,但它不是线程安全的(实际上它是线程安全的,但并发调用将被阻塞并按顺序执行)=>不要将它缓存在多线程环境中。

这是一个 好文章 进一步细节。


10
2018-05-31 21:39



我不相信这是真的。通道是线程安全的。 - Bart
@Tom C.这是一个 好文章 进一步细节。根据它,通道确实是线程安全的,但会阻止并发访问并按顺序执行它们。 - Darin Dimitrov
根据使用的WCF选项,通道可以包含特定会话的特定状态。所以最好的建议是:缓存工厂,而不是渠道。 - Drew Marsh
是的,我同意在同一个通道上的并发调用将按顺序执行,并且可能是多线程环境中的问题。但这可以通过渠道池来解决。创建频道可能不如创建ChannelFactory那么昂贵,但仍然需要付出代价。而且这种成本随着时间的推移而增加,并且对于某些高性能系统来说是不可接受的。 - Bart
也许微软认为大多数软件系统都可以在没有缓存通道性能的情况下生存,但这仍然无法解释为什么微软迫使开发人员控制通道清理。为什么开发人员必须将其代理转发到IClientChannel,以便开发人员可以确定是否在通道上调用Close()/ Abort()/ Dispose()。为什么不能将此作为垃圾收集的一部分自动完成,因为频道超出了范围。 - Bart