WCF初探-12:WCF客户端异常处理
前言:
- 当我们打开WCF基础客户端通道(无论是通过显式打开还是通过调用操作自动打开)、使用客户端或通道对象调用操作,或关闭基础客户端通道时,都会在客户端应用程序中出现异常。而我们知道WCF是基于网络的通讯服务,错误异常也是要基于消息传递的,在WCF中提供了一个错误消息处理的类FaultException。接下来,我们看一下如何使用它在客户端处理异常。
WCF异常类型:
- 意外异常:意外异常包括灾难性故障(如 OutOfMemoryException)和编程错误(如 ArgumentNullException 或 InvalidOperationException)。通常没有有效的方法来处理意外错误,所以通常不应在调用 WCF 客户端通信方法时捕获这些异常。
- 预期异常:预期异常包括 TimeoutException、CommunicationException 以及 CommunicationException 的任何派生类。这些异常表明通信过程中出现问题,该问题可以通过中止 WCF 客户端并报告通信故障而得到安全的处理。因为外部因素可能导致任何应用程序中出现这些错误,所以正确的应用程序必须捕获这些异常并在发生异常时进行恢复。
WCF客户端异常处理示例:
- 工程结构如下图所示:
- 工程结构说明:
- Service:类库程序。定义和实现服务契约,包含Add()和Divide(),即加法和除法运算。
ICalculator.cs代码如下:
using System.ServiceModel;
using System.Collections.Generic;
using System.Runtime.Serialization; namespace Service
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
int Add(int value1, int value2); [OperationContract]
int Divide(int value1, int value2);
} }
Calculator.cs代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel; namespace Service
{
public class Calculator:ICalculator
{
public int Add(int value1, int value2)
{
return value1 + value2;
} public int Divide(int value1, int value2)
{
try
{
return value1 / value2;
}
catch(DivideByZeroException)
{
throw new FaultException("除数不能为0");
}
}
}
}
2. Host:控制台应用程序。用来承载服务,添加对于Service程序集的引用后,实现以下代码就可以承载服务。
Program.cs的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service;
using System.ServiceModel; namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Calculator)))
{
host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); };
host.Open();
Console.Read();
}
}
}
}
App.config的代码如下:
<?xml version="1.0"?>
<configuration>
<system.serviceModel> <services>
<service name="Service.Calculator" behaviorConfiguration="mexBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/Calculator/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="Service.ICalculator" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
3. Client:控制台应用程序。将Host承载服务启动后,客户端程序添加对服务地址http://localhost:1234/Calculator/的引用,将命名空间设置为CalculatorServiceRef,
接下来我们就可以调用服务呢。Client的Program.cs代码如下:

首先,我们将2、3的代码注释掉,只验证服务异常抛出的结果,我们把Divide的除数设置为0,此时应该会捕获到服务端抛出的异常信息。运行结果如下:

然后,我们把1、3注释,只验证通讯超时的异常抛出。我们将通道连接后的操作时间设置为非常小的一个值,那么服务端的运算肯定来不及处理,就会抛出超
时的异常信息。运行结果如下:

最后,我们将1、2注释,只验证通讯错误异常信息,我们在客户端执行完Add()后,就把服务终止,即服务终止连接则会抛出通讯错误的异常信息,运行结果如下所示:

总结:
- 通过示例,我们可以看到,客户端程序成功捕获到了TimeoutException和CommunicationException以及自定义异常信息
- 如果发生预期异常,客户端或许可以继续使用,或许无法继续使用。若要确定客户端是否仍然可以使用,请检查 State 属性是否为 CommunicationState.Opened。
如果此属性仍然处于打开状态,则客户端仍然可以使用。否则,则应中止客户端并释放对其的所有引用。具体参照代码如下:
if (proxy.State == CommunicationState.Opened){
Console.WriteLine("CommunicationState is Opened");
}

WCF初探-12:WCF客户端异常处理的更多相关文章
- WCF初探文章列表
WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...
- WCF初探-20:WCF错误协定
WCF错误协定概述 在所有托管应用程序中,处理错误由 Exception 对象表示. 在基于 SOAP 的应用程序(如 WCF 应用程序)中,服务方法使用 SOAP 错误消息来传递处理错误信息. SO ...
- WCF初探-10:WCF客户端调用服务
创建WCF 服务客户端应用程序需要执行下列步骤: 获取服务终结点的服务协定.绑定以及地址信息 使用该信息创建 WCF 客户端 调用操作 关闭该 WCF 客户端对象 WCF客户端调用服务存在以下特点: ...
- WCF初探-11:WCF客户端异步调用服务
前言: 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的.有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码 ...
- WCF初探-13:WCF客户端为双工服务创建回调对象
前言: 在WCF初探-5:WCF消息交换模式之双工通讯(Duplex)博文中,我讲解了双工通信服务的一个应用场景,即订阅和发布模式,这一篇,我将通过一个消息发送的例子讲解一下WCF客户端如何为双工服务 ...
- WCF初探-28:WCF中的并发
理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...
- WCF初探-27:WCF中的实例化
理解WCF中的实例化机制 “实例化”是指对用户定义的服务对象以及与其相关的 InstanceContext 对象的生存期的控制.也就是说我们的客户端程序在调用服务端方法时,需要实例化一个服务端代理类对 ...
- WCF初探-26:WCF中的会话
理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调 ...
- WCF初探-2:手动实现WCF程序
1.前言 上一篇,我们通过VS自带的模板引擎自动生成了一个wcf程序,接下来我们将手动实现一个wcf程序.由于应用程序开发中一般都会涉及到大量的增删改查业务,所以这个程序将简单演示如何在wcf中构建简 ...
随机推荐
- geckodriver v0.11.0 github上下载的
从 https://github.com/mozilla/geckodriver/releases 下载的.家里下载不了,selenium 3.0.1 + python 2.7.10 + firefo ...
- 让Docker容器使用静态独立的外部IP(便于集群组建)
需要使用Docker虚拟化Hadoop/Spark等测试环境,并且要可以对外提供服务,要求是完全分布式的部署(尽量模拟生产环境).那么我们会遇到几个问题: Container IP 是动态分配的 Co ...
- spring基础整理
spring基础教程:https://www.tutorialspoint.com/spring/spring_overview.htm 注入实例 <bean id="" c ...
- 基于eBox的LTC1446驱动
LTC1446 是linear出品的双通道12bit轨对轨DAC芯片,采用SPI接口,内部基准电压,满量程输出4.095v,单电源供电(4.5-5v).8Pin封装. 使用时非常 ...
- 使用Redis分布式队列
1.这是处理异常的类 public class MyExceptionAttribute:HandleErrorAttribute { //public static Queue<Excepti ...
- SVN和Git的异同
其实Git和SVN还是挺像的,都有提交,合并等操作,看来这是源码管理工具的基本操作. 1. Git是分布式的,SVN是集中式的,好处是跟其他同事不会有太多的冲突,自己写的代码放在自己电脑上,一段时间后 ...
- Java类的基本运行顺序
不看不知道,一看还真吓了一跳!Java类的基本运行顺序你真的知道吗?如果你有疑惑,那就看下面这篇文章吧. 原文出自:[url]http://column.ibeifeng.com/chenchen ...
- 如何用css做一个细虚线边框表格
<style type="text/css"> <!-- .dashed_tbl { border-top: 1px dashed #333333; border ...
- 关于SSIS中解密数据库字符串的方法
此文章适合于SSIS新手,我是个小白,在繁复查阅资料后仍无果到最后解决问题,走了很多弯路,现在讲其中一些关于SSIS的理解写出来,供大家参考,在正文之前,我就我自己的理解,阐明一些概念. 什么是SSI ...
- linux下cmake编译安装、配置和卸载mysql
WIN10下虚拟机:VMware workstation 12 PRO 安装 # 1.查看系统版本 [root@vm-xiluhua][/home/xiluhua]$ cat /etc/redhat- ...