ChannelFactory.Close VS IClientChannel.Close

Dan*_*ger 33 wcf channelfactory

请考虑以下代码,这些代码是许多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();
Run Code Online (Sandbox Code Playgroud)

请注意,当调用proxy.Open()时,通道的状态和ChannelFactory的状态都变为"已打开".当调用proxy.Close()时,通道的状态变为"关闭",但ChannelFactory的状态仍为"已打开".

是否应该关闭ChannelFactory?在许多例子中我似乎没有看到这一点.另外,如果可能的话,请解释开放频道与开放频道工厂之间的区别.

另外,我知道IDisposable问题,因此除非它对答案有直接影响,否则它可能会被忽略.

Ali*_*tad 18

我发现主答案不准确,所以我在这里回答.

很明显,微软已经彻底搞乱了Channles和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
Run Code Online (Sandbox Code Playgroud)

所以真的,在内部它是完全相同的渠道.我个人已经开始处理渠道工厂而不是客户渠道,并没有遇到任何问题.我也尝试在创建100000个客户端通道的循环中执行此操作,并且仅关闭ChannelFactory.

  • 整个来说,它不是*同一个频道; ChannelFactory.Close循环遍历其频道并手动关闭它们.这就是为什么你得到处置的例外. (36认同)
  • @JoãoPortela跟我说说吧!是的.正如我解释的那样,关闭工厂将关闭底层渠道和客户. (4认同)

JP *_*oto 14

如您所知,ChannelFactory根据配置创建客户端通道.您可能希望从现有工厂创建多个客户端通道(到锁定的端点).如果您已完成使用工厂创建频道,则没有理由不关闭它.

但是,为什么你想让它保持开放?这是一篇关于WCF客户的有趣文章:

检查System.ServiceModel.ICommunicationObject.State属性的值是竞争条件,建议不要确定是重用还是关闭通道.

您可能只想使用通道工厂创建一个新通道,而不是重用通道.关于客户端架构的更多信息在这里.