考虑以下代码,这是许多ChannelFactory示例的典型代码:
WSHttpBinding myBinding = new WSHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress(
ConfigurationSettings.AppSettings["HelloWorldServiceURL"]);
ChannelFactory<IHelloWorldService> myChannelFactory =
new ChannelFactory<IHelloWorldService>(myBinding, myEndpoint);
IHelloWorldService proxy = myChannelFactory.CreateChannel();
((IClientChannel)proxy).Open();
HelloWorldDataContract dc = proxy.SayHello();
((IClientChannel)proxy).Close();
请注意,当调用proxy.Open()时,通道的状态和ChannelFactory的状态都变为“已打开”。当调用proxy.Close()时,通道的状态变为“关闭”,但ChannelFactory的状态仍为“已打开”。
是否还要关闭ChannelFactory?在许多例子中我似乎没有看到这一点。另外,如果可能的话,请解释开放频道与开放频道工厂之间的区别。
此外,我知道IDisposable issue,因此除非对答案有直接影响,否则可能会忽略此问题。
答案 0 :(得分:19)
我发现主要答案不准确,所以我在这里作出回应。
显然,微软已经从Channles and Factories and Clients中做出了一个绝对混乱。文档也没有帮助,因为它们似乎只是为了掩盖这些混乱所以我不得不求助于测试。
由于有关非缓存频道的性能问题,v3.5中的实施已更改以解决这些问题并添加了缓存,但这只会使问题复杂化。
ChannelFactory
中的频道实际上与使用IClientChannel
创建频道时ChannelFactory.CreateChannel()
使用的频道没有什么不同。它都是同一个锅。不相信我?尝试:
ChannelFactory<IService> factory = new ChannelFactory<IService>();
// ...
IService service = factory.CreateChannel();
factory.Close();
service.DoIt() // Throws object disposed exception
所以真的,在内部它是完全相同的渠道。我个人已经开始处理渠道工厂而不是客户渠道,并没有遇到任何问题。我还尝试在创建100000个客户端频道的循环中执行此操作,并且只关闭ChannelFactory
。
答案 1 :(得分:13)
如您所知,ChannelFactory根据配置创建客户端通道。您可能希望从现有工厂创建多个客户端通道(到锁定的端点)。如果您已完成使用工厂创建频道,则没有理由不关闭它。
但是,为什么你要保持开放?这是一个有趣的article on WCF clients,上面写着:
检查。的值 System.ServiceModel.ICommunicationObject.State 财产是一种竞争条件,是 不推荐确定是否 重用或关闭频道。
您可能只想使用渠道工厂创建一个新渠道,而不是重复使用渠道。 More on the client architecture is here
答案 2 :(得分:4)
另一种选择是使用静态CreateChannel方法: msdn.microsoft.com/en-us/library/aa344556.aspx
答案 3 :(得分:1)
答案已经在这里,但是它分散在多个评论和答案中,并且还不完全清楚,因此是我的答案。
是否应该关闭ChannelFactory和Channel?
不。如果要从每个ChannelFactory创建多个Channel,则应该处置ChannelFactory,这将处置它为您创建的所有Channel。
如果要为每个(端点,绑定)对创建一个通道,则应使用this static function:ChannelFactory<ServiceType>.CreateChannel(binding, endpoint)
(这避免了该问题,因为它不会创建第二个IDisposable),并且您应该处理它返回的通道。
处置channelfactory及其创建的任何渠道都会引发ObjectDisposed异常。