33

考虑以下代码,它是许多 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 问题,所以为了这个问题,它可能可以被忽略,除非它对答案有直接影响。

4

4 回答 4

19

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

显然,微软已经把频道、工厂和客户搞得一团糟。文档也没有帮助,因为它们似乎只是为了掩盖混乱,所以我不得不求助于测试。

由于非缓存通道的性能问题,v3.5中的实现进行了更改以解决这些问题并添加了缓存,但这只会使问题复杂化。

关键是 channel in实际上与使用创建通道时使用ChannelFactory的通道没有什么不同。都是同一个锅。不信?尝试:IClientChannelChannelFactory.CreateChannel()

ChannelFactory<IService> factory = new ChannelFactory<IService>();
// ...
IService service = factory.CreateChannel();
factory.Close();
service.DoIt() // Throws object disposed exception

所以实际上,在内部它都是同一个渠道。我个人已经开始处理通道工厂而不是客户端通道,并且没有遇到任何问题。我也尝试在循环中创建 100000 个客户端通道,并且只关闭ChannelFactory.

于 2011-02-15T17:14:48.630 回答
14

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

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

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

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

于 2009-05-14T23:21:37.267 回答
4

另一种选择是使用静态 CreateChannel 方法: msdn.microsoft.com/en-us/library/aa344556.aspx

于 2011-09-14T19:53:06.120 回答
2

答案已经在这里,但它分布在几个评论和答案中,并不完全清楚,因此我的答案是。

是否应该关闭 ChannelFactory 以及 Channel?

不,如果你想从每个 ChannelFactory 创建多个 Channel,你应该处理 ChannelFactory,它会处理它为你创建的所有 Channel。

如果您想为每个(端点、绑定)对创建一个通道,您应该使用这个静态函数:(ChannelFactory<ServiceType>.CreateChannel(binding, endpoint)这可以避免这个问题,因为它不会创建第二个 IDisposable),并且您应该处理它返回的通道。

处理 channelfactory 和它创建的任何通道都会引发 ObjectDisposed 异常。

于 2018-10-25T08:25:57.670 回答