我喜欢在using块中实例化我的WCF服务客户端,因为它几乎是使用实现的资源的标准方法IDisposable:
using (var client = new SomeWCFServiceClient())
{
//Do something with the client
}
Run Code Online (Sandbox Code Playgroud)
但是,正如本MSDN文章中所述,在using块中包装WCF客户端可能会掩盖导致客户端处于故障状态的任何错误(如超时或通信问题).简而言之,当调用Dispose()时,客户端的Close()方法会触发,但会因为处于故障状态而抛出错误.然后,第二个异常掩盖了原始异常.不好.
MSDN文章中建议的解决方法是完全避免使用using块,而是实例化您的客户端并使用它们,如下所示:
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}
Run Code Online (Sandbox Code Playgroud)
与using块相比,我认为这很难看.每次需要客户端时都需要编写很多代码.
幸运的是,我发现了一些其他的解决方法,例如IServiceOriented上的这个.你从:
public delegate void UseServiceDelegate<T>(T proxy);
public static class Service<T>
{
public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>("");
public static void Use(UseServiceDelegate<T> codeBlock)
{ …Run Code Online (Sandbox Code Playgroud) 我一直在研究一个使用WCF访问服务器端逻辑和数据库的WPF应用程序.
我开始使用一个WCF客户端代理对象,我反复使用它来调用服务器上的方法.使用代理一段时间后,服务器最终会抛出异常:
System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at http://.../Service/BillingService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
我认为这是因为每个服务调用都是从代理打开一个新的套接字到服务器,从不关闭它们.最终服务器被淹没并开始拒绝请求.
经过短暂的搜索,我确定我需要定期关闭()代理.我发现的样本简并很小.这个提供了一些有用的提示,但并没有真正回答这个问题.我也看到了避免使用using()模式的建议(并改为使用try/catch/finally),因为代理的Dispose方法可能抛出异常(yuck).
似乎推荐的模式正如此形成:
[TestClass]
public class WCFClientUnitTest
{
BillingServiceClient …Run Code Online (Sandbox Code Playgroud)