WCF初探-12:WCF客戶端異常處理

前言:

 

  • 當咱們打開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);
    }

}
View Code

  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");
            }
        }
    }
}
View Code

  2.  Host:控制檯應用程序。用來承載服務,添加對於Service程序集的引用後,實現如下代碼就能夠承載服務。網絡

      Program.cs的代碼以下:ide

  
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();
            }
        }
    }
}
View Code

  App.config的代碼以下:spa

  
<?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>
View Code

  3.  Client:控制檯應用程序。將Host承載服務啓動後,客戶端程序添加對服務地址http://localhost:1234/Calculator/的引用,將命名空間設置爲CalculatorServiceRef,3d

    接下來咱們就能夠調用服務呢。Client的Program.cs代碼以下:code

  

    首先,咱們將二、3的代碼註釋掉,只驗證服務異常拋出的結果,咱們把Divide的除數設置爲0,此時應該會捕獲到服務端拋出的異常信息。運行結果以下:xml

  

   而後,咱們把一、3註釋,只驗證通信超時的異常拋出。咱們將通道鏈接後的操做時間設置爲很是小的一個值,那麼服務端的運算確定來不及處理,就會拋出超對象

   時的異常信息。運行結果以下:blog

  

    最後,咱們將一、2註釋,只驗證通信錯誤異常信息,咱們在客戶端執行完Add()後,就把服務終止,即服務終止鏈接則會拋出通信錯誤的異常信息,運行結果以下所示:

  

總結:

 

  • 經過示例,咱們能夠看到,客戶端程序成功捕獲到了TimeoutException和CommunicationException以及自定義異常信息
  • 若是發生預期異常,客戶端或許能夠繼續使用,或許沒法繼續使用。若要肯定客戶端是否仍然能夠使用,請檢查 State 屬性是否爲 CommunicationState.Opened。

    若是此屬性仍然處於打開狀態,則客戶端仍然能夠使用。不然,則應停止客戶端並釋放對其的全部引用。具體參照代碼以下:

if (proxy.State == CommunicationState.Opened){
    Console.WriteLine("CommunicationState is Opened");
 }

 

相關文章
相關標籤/搜索