本文让你可以看到如何正确地关闭这些通信的连接。
如果你使用过Visual Studio为WCF服务生成WCF代理类,那么现在来看看里面生成的客户端类:
- public partial class StockServiceClient : System.ServiceModel.ClientBase<StockService.IStockService>, StockService.IStockService {
- ...
客户端使用的主要代码继承自ClientBase<>,在MSDN看到它实现了IDisposable接口。与大多数实现IDisposable接口的类一样,为WCF客户端使用C#的using声明将是吸引人的。
- // 虽然很棒,但不能这样写:
- using(StockService.StockServiceClient client = new StockService.StockServiceClient(
- "StockBasicHttpEndpoint", stockServiceUrl))
- {
- client.GetStockIdByName("MSFT");
- }
如你所知,这样使用将在通信完成后自动调用client.Dispose()方法。这样就有一个问题,通过ClientBase类的Dispose()方法调用了Close()方法。当ClientBase类的Close()方法被调用后,Web服务实际上停止了WCF服务并通知它连接会话已不再需要保持。这似乎违反常理,但确实发生了。这个问题的解决办法是当Close()方法被调用后能抛出一个异常。毕竟,它涉及的是对Web服务的另一个网络调用。正因为如此,在WCF客户端是不推荐使用using声明的。
相反,你应该尝试在一个try-catch代码块执行Close()方法,在catch里执行Abort()方法。
- //正常调用Web服务.
- StockService.StockServiceClient client = new StockService.StockServiceClient(
- "StockBasicHttpEndpoint", stockServiceUrl);
- string StockId = client.GetStockIdByName("MSFT");
- //服务完成后,使它关闭
- try
- {
- if (client.State != System.ServiceModel.CommunicationState.Faulted)
- {
- client.Close();
- }
- }
- catch (Exception ex)
- {
- client.Abort();
- }
如果你使用完全相同的关闭代码,那么上述解决方法也适用于ChannelFactory类。
- //从工厂创建通道channel实例
- ChannelFactory channel =
- new ChannelFactory<IService1>("bindingName");
- IService1 client = channel.CreateChannel();
- client.DoWork();
- //服务完成后,使它关闭
- try
- {
- if (client.State != System.ServiceModel.CommunicationState.Faulted)
- {
- client.Close();
- }
- }
- catch (Exception ex)
- {
- client.Abort();
- }
就这些,非常简单。不要对WCF的client类使用'using';在try-catch块里调用Close()方法关闭客户端,异常发生后调用Abort()方法。
英文链接:Closing your WCF Connections properly