麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

正確捕獲 WCF服務(wù)調(diào)用中發(fā)生的異常及處理技巧

2019-11-17 03:52:46
字體:
供稿:網(wǎng)友
概述:本節(jié)主要講述在服務(wù)調(diào)用中可能發(fā)生的異常及模擬異常的發(fā)生,并分析何時可捕獲何種異常,以及如何把服務(wù)異常以正確的方式傳遞到客戶端,

          文章最后給出正確捕獲異常的捕獲順序。本次異常捕獲僅為介紹,部分為應(yīng)用性功能,所以代碼和行文相對簡單,還介紹了在服務(wù)器端異常處理的一些技巧。

1、  首先,我們創(chuàng)建一個簡單的計算器服務(wù)器和客戶端,如下:



點擊展開代碼
//服務(wù)器[ServiceContract]public interface ICalc{[OperationContract][FaultContract(typeof(GreentingError))]string Div(int x, int y);}public class Calc : ServiceBase, ICalc    {public string Div(int x, int y)        {string result = string.Empty;            try            {result = string.Format("result: {0}", x / y); } catch (DivideByZeroException ex)            {throw ex; }return result; }}//客戶端[ServiceContract]    public interface ICalc    {        [OperationContract]        [FaultContract(typeof(GreentingError))]        string Div(int x, int y);    }public class CalcClient : ClientBase<ICalc>, ICalc{ public string Div(int x, int y) {return base.Channel.Div(x, y); }}
好吧,我承認代碼相當?shù)暮唵危贿^我喜歡簡潔的東西。





2、 簡單的東西就是好,調(diào)用都簡單得多;我們來調(diào)用一下。       

        try            {                CalcClientcalcclient = new CalcClient();                string result =calcclient.Div(10, 0);                Console.WriteLine(result);                Console.ReadKey();            }            catch (TimeoutExceptionex) {throw ex; }            catch (FaultException<GreentingError> ex) {throw ex; }            catch (FaultExceptionex) {throw ex;            catch (System.ServiceModel.CommunicationException ex) {throw ex; }            catch (Exceptionex) {throw ex; }





3、當我們在調(diào)用服務(wù)的Div(int x,int y)方法并給對數(shù)y傳遞了值為0后,服務(wù)器端將會引發(fā)DivideByZeroException的異常,這在預(yù)料之中。這時候,

在客戶端的FaultException部分捕獲了這個異常。



4、沒問題,我們再在服務(wù)器代碼中手動拋出FaultException異常。



catch (DivideByZeroException ex){FaultException exception = new FaultException(ex.Message); throw exception;}


這時候發(fā)現(xiàn),還是FaultException捕獲了這個異常,為何?



5、再做一個測試。

在服務(wù)加入這句代碼:System.Threading.Thread.Sleep(70000);使得服務(wù)超時。

這回終于是TimeOutException捕獲了服務(wù)器的異常,那么我們就要問了,F(xiàn)aultException< GreentingError>何時會捕獲異常呢?答案是當服務(wù)器拋出FaultException< GreentingError>的時候,引用MSDN上的一段話(綠色部分):

如果偵聽器接收到操作協(xié)定中不期望或未指定的 SOAP 錯誤,將會引發(fā) FaultException對象, 可以發(fā)送兩種類型的 SOAP 錯誤:已聲明的和未聲明的。 已聲明的 SOAP 錯誤是指其中的某個操作具有System.ServiceModel.FaultContractAttribute屬性(用于指定自定義 SOAP 錯誤類型)的錯誤。 未聲明的 SOAP 錯誤是在操作的協(xié)定中沒有指定的錯誤。這里的“不期望或未指定的 SOAP 錯誤”是指未在服務(wù)操作中應(yīng)用FaultContractAttribute包裝的自定義錯誤類型。



6、那么何時會捕獲CommincationException異常呢?

MSDN上說是:應(yīng)用程序處理在通信期間可能會引發(fā)的 CommunicationException 對象

好吧,為了引發(fā)這個異常,我們來作如下操作。首先在服務(wù)器關(guān)閉當前通道對象。



OperationContext.Current.Channel.Close();
很遺憾,客戶端并沒有捕獲到CommunicationException,而是捕獲到了TimeOutException異常!因為服務(wù)通道關(guān)閉后,并未發(fā)生異常,所以沒有返回消息到客戶端,客戶端在等待一定時間后,超時退出。



所以我們在關(guān)閉通道的同時指定一個TimeSpan。這樣可以讓調(diào)用立即返回,當然,還可以通過Channel.Abort來完成調(diào)用返回。



OperationContext.Current.Channel.Close(new TimeSpan(5000));


在調(diào)用了IContextChannel的Close方法的同時,指定在超時前必須完成發(fā)送操作的時間,這樣可以使得消息在指定時間內(nèi)立即返回,而不必等到服務(wù)調(diào)用超時,否則到時客戶端必將引發(fā)TimeOutException異常,而不是CommunicationException異常。

7、補救措施

同時,為了在服務(wù)出現(xiàn)異常時我們可以采取一些補救的措施,我們新建了一個抽象類ServiceBase,并使得Calc服務(wù)實現(xiàn)類繼承自它,這樣我們就可以在服務(wù)各種狀態(tài)轉(zhuǎn)換中取得控制權(quán)。ServiceBase類如下:




public abstract partial class ServiceBase    {        PRivate IContextChannel channel = null;        protected ServiceBase()        {            channel = OperationContext.Current.Channel;            channel.Opening += new EventHandler(delegate(object sender, EventArgs e) {/* TO DO*/ });            channel.Opened += new EventHandler(delegate(object sender, EventArgs e) {/* TO DO*/ });            channel.Closing += new EventHandler(delegate(object sender, EventArgs e) {/* TO DO*/ });            channel.Closed += new EventHandler(delegate(object sender, EventArgs e) { Abort(); });            channel.Faulted += new EventHandler(delegate(object sender, EventArgs e) { Abort(); });        }        void Open() {/* TO DO*/ }        void Close() { /* TO DO*/}        void Abort() { channel.Abort(); }}


從上面的代碼中可以看出,在服務(wù)通道關(guān)閉以后,我們立即將服務(wù)中止,讓消息立即返回,這時候即使在操作中關(guān)閉了服務(wù)而又未指定超時完成的時間,調(diào)用依然可以立即返回。

這次客戶端總算捕獲到了CommunicationException異常,見下圖:



為何會這樣?



8、讓我們來看一下CommunicationException的繼承層次,從中我們可以得到啟示。

8.1、首先是FaultException<TDetail>的繼承層次。



8.2、再次是TimeOutException的繼承層次。



9、從上圖中可以看出,TimeOutException和CommunicationException均繼承自SystemException類,而FaultException繼承自CommunicationException,最后是FaultException<TDetail>繼承自FaultException類。

10、最后我們得出,在客戶端正確的捕獲異常的順序應(yīng)該是:

TimeOutException> FaultException<TDetail> > FaultException >CommunicationException > Exception。在這里強烈建議開發(fā)人員拋出和捕獲FaultException<TDetail>類型的異常。

作者:老米
    
出處:http://www.companysz.com/viter/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權(quán)利。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美日韩国产中文字幕 | 国产91精品久久久久久 | 亚洲骚妻| 亚洲一区国产二区 | 国产精品刺激对白麻豆99 | 黄色片在线免费播放 | 国产成人在线免费视频 | 91福利在线观看 | 日韩a毛片免费观看 | 操操操操网 | 国语自产免费精品视频在 | 欧美成人精品h版在线观看 久久久久久三区 | 国产色视频免费 | 欧美级毛片 | 精品一区二区6 | 欧美成人激情在线 | 新久草视频 | 欧美 中文字幕 | 91色一区二区三区 | 最新久久免费视频 | 国产成年人在线观看 | 欧美不卡在线 | 视屏一区 | 免费黄色大片在线观看 | 欧美一级高清片在线 | 海角在线观看91一区二区 | 91中文在线 | 日本精品视频一区二区三区四区 | 高清视频一区二区 | 久久国产精品99国产 | 蜜桃av鲁一鲁一鲁一鲁 | 久久网页 | 欧美成人视| 免费一级毛片免费播放 | 欧美特黄特色视频 | 欧美黄 片免费观看 | 成品片a免人视频 | 中文字幕在线永久视频 | 国产午夜精品久久久 | 黄色片免费看网站 | 免费一级在线观看 |