关闭WCF连接

31
我们正在使用WCF服务。 在客户端,我们计划显式关闭连接。似乎有多种关闭方法。
示例1: 在WCF服务调用的finally块中使用。
if (client.State == CommunicationState.Faulted)
{
  client.Abort();
}
client.Close();

由于如果服务处于故障状态,我们将无法调用close()方法。

示例2:

using(ClientProxy proxy = new ClientProxy())
{   
  //call your service methods
}

对于sample2,如果服务处于故障状态,我不确定会发生什么情况,它会抛出错误并关闭连接吗?


@Balaji- 看看这篇文章吧- https://dev59.com/6nRB5IYBdhLWcg3wn4QL 。它非常有帮助。 - RichardOD
4个回答

37

您手头已经有了所有必要的信息 - 适当使用并关闭/中止所有WCF客户端代理的最佳实践如下:

YourClientProxy clientProxy = new YourClientProxy();

try
{
   .. use your service
   clientProxy.Close();
}
catch(FaultException)
{
   clientProxy.Abort();
}
catch(CommunicationException)
{
   clientProxy.Abort();
}
catch (TimeoutException)
{ 
   clientProxy.Abort();
}

使用Catching the FaultException可以处理服务响应错误的所有情况(因此您的通道处于故障状态),而CommunicationException将处理可能发生的所有其他与通信相关的异常,例如网络连接中断等。

在using()块中采用的方法行不通,因为如果在块的末尾发生异常,当Dispose()方法调用客户端代理的Close()方法时,您无法捕获和处理该异常。


感谢大家的回复。 我希望在web.config文件中有一些设置来处理连接关闭的问题! - Balaji
1
FaultException是CommunicationException,所以从技术角度来说,你不需要两个catch子句(除非你打算以不同的方式处理这两种情况)。 - bobbymcr
FaultException是CommunicationException的子类,你说得对 - 只处理CommunicationException就可以了,只要你不需要为这两种不同情况做不同的事情。我猜这只是我的习惯,即使我在它们中的任何一个中都没有做任何特殊的事情,也会单独列出最常见的异常类型..... - marc_s
@BrentArias:请不要在我的答案中加入你的大段陈述——如果你有额外的话要说,你可以添加自己的答案来进一步解释我所说的内容。谢谢。 - marc_s

19

使用“using”块的第2个示例是不正确的。使用块确保在代理对象上调用Dispose方法。然后,Dispose方法调用Close方法,该方法将尝试连接到服务,当通信状态出现故障时会引发异常。因此,您的感觉/直觉是绝对正确的。如果代理Dispose方法使用您第一个示例中的代码,那就太好了,但它没有,所以不要使用using块 :)


4
在Juval Lowy的优秀编程WCF书籍中,他建议:
try 
{
    ClientProxy clientProxy = new ClientProxy();
    clientProxy.SomeMethod();
    clientProxy.Close();
}
catch
{
    proxy.Abort();
}

2
哈..我在书中看到了那段代码,但我认为它无法编译。服务必须在try块之外声明,以便在catch块中访问...然后您可能想要在其周围放置一个null检查。 - foson
@foson- 你知道它在哪一页吗?你对上面的代码是正确的。我有这本书,但是我之前读过一段时间了。 - RichardOD

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接