前言:

  • 当我们打开WCF基础客户端通道(无论是通过显式打开还是通过调用操作自动打开)、使用客户端或通道对象调用操作,或关闭基础客户端通道时,都会在客户端应用程序中出现异常。而我们知道WCF是基于网络的通讯服务,错误异常也是要基于消息传递的,在WCF中提供了一个错误消息处理的类FaultException。接下来,我们看一下如何使用它在客户端处理异常。

WCF异常类型:

  • 意外异常:意外异常包括灾难性故障(如 OutOfMemoryException)和编程错误(如 ArgumentNullException 或 InvalidOperationException)。通常没有有效的方法来处理意外错误,所以通常不应在调用 WCF 客户端通信方法时捕获这些异常。
  • 预期异常:预期异常包括 TimeoutException、CommunicationException 以及 CommunicationException 的任何派生类。这些异常表明通信过程中出现问题,该问题可以通过中止 WCF 客户端并报告通信故障而得到安全的处理。因为外部因素可能导致任何应用程序中出现这些错误,所以正确的应用程序必须捕获这些异常并在发生异常时进行恢复。

WCF客户端异常处理示例:

  • 工程结构如下图所示:

  

  • 工程结构说明:
  1. 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客户端异常处理的更多相关文章

  1. WCF初探文章列表

    WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...

  2. WCF初探-20:WCF错误协定

    WCF错误协定概述 在所有托管应用程序中,处理错误由 Exception 对象表示. 在基于 SOAP 的应用程序(如 WCF 应用程序)中,服务方法使用 SOAP 错误消息来传递处理错误信息. SO ...

  3. WCF初探-10:WCF客户端调用服务

    创建WCF 服务客户端应用程序需要执行下列步骤: 获取服务终结点的服务协定.绑定以及地址信息 使用该信息创建 WCF 客户端 调用操作 关闭该 WCF 客户端对象 WCF客户端调用服务存在以下特点: ...

  4. WCF初探-11:WCF客户端异步调用服务

    前言: 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的.有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码 ...

  5. WCF初探-13:WCF客户端为双工服务创建回调对象

    前言: 在WCF初探-5:WCF消息交换模式之双工通讯(Duplex)博文中,我讲解了双工通信服务的一个应用场景,即订阅和发布模式,这一篇,我将通过一个消息发送的例子讲解一下WCF客户端如何为双工服务 ...

  6. WCF初探-28:WCF中的并发

    理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...

  7. WCF初探-27:WCF中的实例化

    理解WCF中的实例化机制 “实例化”是指对用户定义的服务对象以及与其相关的 InstanceContext 对象的生存期的控制.也就是说我们的客户端程序在调用服务端方法时,需要实例化一个服务端代理类对 ...

  8. WCF初探-26:WCF中的会话

    理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调 ...

  9. WCF初探-2:手动实现WCF程序

    1.前言 上一篇,我们通过VS自带的模板引擎自动生成了一个wcf程序,接下来我们将手动实现一个wcf程序.由于应用程序开发中一般都会涉及到大量的增删改查业务,所以这个程序将简单演示如何在wcf中构建简 ...

随机推荐

  1. Android--Retrofit+RxJava的简单封装(三)

    1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...

  2. java 笔试题 字符串旋转

    package com.shb.java; /** * 取出第一个重复的字符 * @author shaobn * @date 2016-9-28 * @package_name com.shb.ja ...

  3. Struts2 配置详解

    1. web.xml 此文件的配置可以参看struts2的示例文档 <filter> <filter-name>struts2</filter-name> < ...

  4. 关于安装qt之后的qmake命令

    今天通过在archlinux中安装qt5发现了关于qmake这个命令的一些事情. 1. /bin/qmake 是 /bin/qtchooser 的符号链接,/bin/qtchooser 由一个叫 qt ...

  5. js asp.net获取时间戳

    方法1: var timestamp = (new Date()).valueOf(); 结果:1280977330748 方法2: var timestamp=new Date().getTime( ...

  6. iOS性能优化:Instruments

    检测内存泄露:Instruments中的Leaks 前言 如果要检测内存泄露,我们会使用Xcode7自带的Instruments中的Leaks工具来检测. 现在的开发环境是ARC,所以很少会出现内存泄 ...

  7. 《C#编程》课件 - C#基础

    声明多维数组• 创建一个多维数组int[,] intMatrix;float[,] floatMatrix;string[,,] strCube;使用new关键字• 必须指定每个维度的大小int[,] ...

  8. WIN10 安装不了NET3.5

    第一步,挂载或插入安装光盘.在sources\sxs文件夹中会有一个“microsoft-windows-netfx3-ondemand-package.cab”文件.Win+X,以管理员权限启动命令 ...

  9. gfortran编译Fortran数组问题

    可能是IVF(inter visual fortran)比LF(lahey Fortran)编译器比较严格的原因 real :: A(L,M) = (/ 1,2,3,4,5,6,7,8,9,10,11 ...

  10. 2016年12月25日 星期日 --出埃及记 Exodus 21:20

    2016年12月25日 星期日 --出埃及记 Exodus 21:20 "If a man beats his male or female slave with a rod and the ...