ChannelFactory.Close VS IClientChannel.Close

时间:2009-05-14 22:59:29

标签: 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();

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

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

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

4 个答案:

答案 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 functionChannelFactory<ServiceType>.CreateChannel(binding, endpoint)(这避免了该问题,因为它不会创建第二个IDisposable),并且您应该处理它返回的通道。

处置channelfactory及其创建的任何渠道都会引发ObjectDisposed异常。