在项目中采用wcf通讯,客户端很多地方调用服务,需要统一的处理超时和通讯异常以及关闭连接。

1.调用尝试和异常捕获

首先,项目中添加一个通用类ServiceDelegate.cs

 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)
{
T proxy = _channelFactory.CreateChannel();
bool success = false; Exception mostRecentEx = null;
for(int i=; i<; i++) // Attempt a maximum of 5 times
{
try
{
codeBlock(proxy);
proxy.Close();
success = true;
break;
} // The following is typically thrown on the client when a channel is terminated due to the server closing the connection.
catch (ChannelTerminatedException cte)
{
mostRecentEx = cte;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep( * (i + ));
} // The following is thrown when a remote endpoint could not be found or reached. The endpoint may not be found or
// reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable.
catch (EndpointNotFoundException enfe)
{
mostRecentEx = enfe;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep( * (i + ));
} // The following exception that is thrown when a server is too busy to accept a message.
catch (ServerTooBusyException stbe)
{
mostRecentEx = stbe;
proxy.Abort(); // delay (backoff) and retry
Thread.Sleep( * (i + ));
} catch(Exception )
{
// rethrow any other exception not defined here
// You may want to define a custom Exception class to pass information such as failure count, and failure type
proxy.Abort();
throw ;
}
}
if (mostRecentEx != null)
{
proxy.Abort();
throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
} }
}

然后,这样调用:

无返回值:

Service<IOrderService>.Use(orderService=>
{
  orderService.PlaceOrder(request);
}

有返回值:

int newOrderId = 0; // need a value for definite assignment
Service<IOrderService>.Use(orderService=>
  {
    newOrderId = orderService.PlaceOrder(request);
  });
Console.WriteLine(newOrderId); // should be updated

2.使用Using方式确保关闭

在客户端扩展一个wcf client的部分类,重写Dispose方法,代码如下:

 namespace 命名空间要和生成的代码里一致
{
/// <summary>
/// ExtDataClient
/// </summary>
public partial class *****Client : IDisposable
{
#region IDisposable implementation /// <summary>
/// IDisposable.Dispose implementation, calls Dispose(true).
/// </summary>
void IDisposable.Dispose()
{
Dispose(true);
} /// <summary>
/// Dispose worker method. Handles graceful shutdown of the
/// client even if it is an faulted state.
/// </summary>
/// <param name="disposing">
/// Are we disposing (alternative
/// is to be finalizing)
/// </param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (State != CommunicationState.Faulted)
{
Close();
}
}
finally
{
if (State != CommunicationState.Closed)
{
Abort();
}
}
}
} /// <summary>
/// Finalizer.
/// </summary>
~*****Client()
{
Dispose(false);
} #endregion
}
}

调用的地方可以直接使用using包起来了
using(****Client client=new ****Client()){//处理逻辑,可以使用try包起来}

3.我自己用到的处理方式,实现一个服务调用单例类,每个服务实现一个调用方法

    /// <summary>
/// 调用SysSvc服务,统一处理TimeoutException和CommunicationException异常
/// 用法:
/// List<ModuleEO/> list = SvcClient.Instance.SysClientCall(q => q.GetAllModules());
/// </summary>
/// <typeparam name="TResult">返回值</typeparam>
/// <param name="func">调用的方法</param>
/// <returns>泛型返回值</returns>
public TResult SysClientCall<TResult>(Func<SysClient, TResult> func)
{
var client = this.GetSysClient();
try
{
TResult rec = func.Invoke(client);
client.Close();
return rec;
}
catch (TimeoutException ex)
{
//服务器超时错误,提示用户即可。
client.Abort();
MessageBox.Show("服务器通讯超时,请重新尝试。");
}
catch (CommunicationException ex)
{
//服务器连接通讯异常,提示用户即可。
client.Abort();
MessageBox.Show("服务器通讯错误,请重新尝试。");
}
catch (Exception ex)
{
//未处理异常,重新抛出
client.Abort();
throw;
}
return default(TResult);
}

参考链接:

http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue

http://stackoverflow.com/questions/6130331/how-to-handle-wcf-exceptions-consolidated-list-with-code

Wcf Client 异常和关闭的通用处理方法的更多相关文章

  1. (转)Do not use "using" for WCF Clients - 不要将WCF Client 放在 ‘Using’ 代码块中

    RT,最近在编写WCF的应用程序,发现WCF client在关闭的时候有可能会抛出异常,经过搜索之后,发些小伙伴们也遇到过类似的问题,遂记载下来,以备自身和其他小伙伴查看. 原文链接:http://w ...

  2. .NET Core开发日志——WCF Client

    WCF作为.NET Framework3.0就被引入的用于构建面向服务的框架在众多项目中发挥着重大作用.时至今日,虽然已有更新的技术可以替代它,但对于那些既存项目或产品,使用新框架重构的代价未必能找到 ...

  3. WCF Client is Open Source

    WCF Client is Open Source Wednesday, May 20, 2015 Announcement New Project WCF We’re excited to anno ...

  4. 获得WCF Client端的本地端口 z

    当WCF调用远程服务时,显示该调用的网速或流量.其中比较关键的一步就是需要获得WCF  Client端的本地端口,原来以为是个简单的事情,结果查了1个多小时谷歌,硬是没找到好的法子,只有自己动手了. ...

  5. (转)wcf client与webservice通信(-)只修改配置文件而改变服务端

    http://www.cnblogs.com/yiyisawa/archive/2008/12/16/1356191.html 问题: 假设有一个大型系统新版本使用wcf 作为服务端,生成wcf cl ...

  6. WCF连接被意外关闭

    WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭 在我们开发WCF项目的时候,常常会碰到一些莫名其妙的错误,有时候如果根据它的错误提示信息,一般很难定位到具体的问题所在,而由于W ...

  7. 获得WCF Client端的本地端口

    获得WCF Client端的本地端口 最近需要做个小功能,当WCF调用远程服务时,显示该调用的网速或流量.其中比较关键的一步就是需要获得WCF  Client端的本地端口,原来以为是个简单的事情,结果 ...

  8. A potentially dangerous Request.Path value was detected from the client异常解决方案

    场景: 当URL中存在“<,>,*,%,&,:,/”特殊字符时,页面会抛出A potentially dangerous Request.Path value was detect ...

  9. Error in WCF client consuming Axis 2 web service with WS-Security UsernameToken PasswordDigest authentication scheme

    13down votefavorite 6 I have a WCF client connecting to a Java based Axis2 web service (outside my c ...

随机推荐

  1. 一个封装较好的删除方法(Delete)

    前台的引用 @Html.ActionLink(“删除字样”,“后台的删除方法”,new{绑定id},new{@style="样式"});方法,如何要独立使用的话,一般还要使用到相应 ...

  2. 关于Socket的经验小结

    前言 IM通信在互联网发展到现在已经是码农的世界里人尽皆知的技术,特别在当下移动互联网迅猛发展的时代这种技术的开发也更加火热,其中老牌的代表作就有QQ和MSN,和最近新崛起的微信,默默,易信,来往等眼 ...

  3. Android性能优化典范(二)

    Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...

  4. ZendStudio的配置导出

    File(文件)->Export(导 出),再弹出Export窗口中点击"General(常规)",选择"Preferences(首选项)" 点击&quo ...

  5. 【CDN】海外免费加速CDN:Incapsula,CloudFare

    最近服务器要搬迁到香港,因为后续有国外用户使用,基于此要使用大陆和海外都比较好的cdn才好 一开始国外同事推荐CloudFare,后来看看效果开始使用Incapsula CloudFare 官网:ht ...

  6. 转:对TCP/IP网络协议的深入浅出归纳

    转自:http://blog.jobbole.com/74795/ 前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没 ...

  7. java集合和scala集合互转

    使用 scala.collection.JavaConverters 与Java集合交互.它有一系列的隐式转换,添加了asJava和asScala的转换方法.使用它们这些方法确保转换是显式的,有助于阅 ...

  8. python的变量传递

    python中变量都被视为对象的引用.python函数调用传递参数的时候,不允许程序员选择传值还是传引用,python参数传递采用的都是“传对象引用”的方式.     这种方式相当于传值和传引用的结合 ...

  9. (转)springAOP解析-2

    原文地址:http://hzbook.group.iteye.com/group/wiki/2262-Spring 3.3.4  AOP拦截器链的调用在了解了对目标对象的直接调用以后,我们开始进入AO ...

  10. DOS命令行中的双引号

    在DOS命令窗口下,运行C:\Program Files\WinRAR\WinRAR.exe,提示如下错误: 因为C:\Program Files\WinRAR\WinRAR.exe中含有空格,它被分 ...