日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WCF中的Dispose

發布時間:2024/1/17 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WCF中的Dispose 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在我翻譯的InfoQ新聞《WCF的問題和Using語句塊》中提到了釋放客戶端資源(其中包括端口、通道)和關閉連接的問題。新聞并沒有很深入地討論,所以我想再補充一些內容。

毫無疑問,在.NET Framework中,一個資源(尤其是非托管資源)通常都需要實現IDisposable接口。一旦實現了該接口,我們就可以使用using語句來管理資源,這是最便捷的方式。但是,一旦在using語句中拋出了異常,就可能不會正確完成資源的回收,尤其是連接,很可能會一直打開,既占用了通道和端口,還可能出現資源的浪費,從而影響系統的性能和穩定性。

微軟推薦的最佳實踐是拋棄using語句,轉而利用try/catch(/finally)語句。它要求在try語句中調用Close()方法,而在catch中調用Abort()方法。在新聞中已經說明了Close()與Abort()方法的區別,即后者可以強制地關閉客戶端,包括關閉客戶端連接,釋放資源。由于Close()方法可能會拋出CommunicationException和TimeoutException異常,通常的客戶端代碼應該是這樣:

var myClient =?new?MyClient();
try
{
????//其他代碼
??? myClient.Close();
}
catch?(CommunicationException)
{
??? myClient.Abort();
}
catch?(TimeoutException)
{
??? myClient.Abort();
}
catch?(Exception)
{
??? myClient.Abort();
????throw;
}

在最后增加對Exception異常的捕獲很有必要,因為我們不知道Close()方法會否拋出某些不可預知的異常,例如OutOfMemoryException等。新聞中提到Steve Smith的方法其實就是對這段冗長代碼的封裝,封裝方式是采用擴展方法,擴展的類型為ICommunicationObject。這是因為所有的客戶端對象都實現了ICommunicationObject接口。以下是Steve Smith的擴展方法代碼:

public?static?class?Extensions
{
????public?static?void?CloseConnection(this?ICommunicationObject myServiceClient)
????{
????????if?(myServiceClient.State != CommunicationState.Opened)
????????{
????????????return;
????????}
????????try
????????{
??????????? myServiceClient.Close();
????????}
????????catch?(CommunicationException ex)
????????{
??????????? Debug.Print(ex.ToString());
??????????? myServiceClient.Abort();
????????}
????????catch?(TimeoutException ex)
????????{
??????????? Debug.Print(ex.ToString());
??????????? myServiceClient.Abort();
????????}
????????catch?(Exception ex)
????????{
??????????? Debug.Print(ex.ToString());
??????????? myServiceClient.Abort();
????????????throw;
????????}
????}
}

?利用該擴展方法,在本應調用Close()方法的地方,代替為CloseConnection()方法,就可以避免寫冗長的catch代碼。而使用Lambda表達式的方式可以說是獨辟蹊徑,使用起來與using語法大致接近。實現方法是定義一個靜態方法,并接受一個ICommunicationObject對象與Action委托:

public?class?Util
{
????public?static?void?Using<T>(T client, Action action)
??????? where T : ICommunicationObject
????{
????????try
????????{
??????????? action(client);
??????????? client.Close();
????????}
????????catch?(CommunicationException)
????????{
??????????? client.Abort();
????????}
????????catch?(TimeoutException)
????????{
??????????? client.Abort();
????????}
????????catch?(Exception)
????????{
??????????? client.Abort();
????????????throw;
????????}
????}
}

?使用時,可以將原本的客戶端代碼作為Action委托的Lambda表達式傳遞給Using方法中:

Util.Using(new?MyClient(), client =>
????{
??????? client.SomeWCFOperation();
????????//其他代碼;
????});

?還有一種方法是定義一個自己的ChannelFactory,讓其實現IDisposable接口,并作為ChannelFactory的Wrapper類。在該類中定義Close()和Dispose()方法時,考慮到異常拋出的情況,并在異常拋出時調用Abort()方法。這樣我們就可以在using中使用自定義的ChannelFactory類。例如:

public?class?MyChannelFactory:IDisposable
{
????private?ChannelFactory m_innerFactory;
????public?MyChannelFactory(ChannelFactory factory)
????{
??????? m_innerFactory = factory;
????}
??? ~MyChannelFactory()
????{
??????? Dispose(false);
????}
????public?void?Close()
????{
??????? Close(TimeSpan.FromSeconds(10));
????}
????public?void?Close(TimeSpan span)
????{
????????if?(m_innerFactory !=?null)
????????{
????????????if?(m_innerFactory.State != CommunicationState.Opened)
????????????{
????????????????return;
????????????}
????????????try
????????????{
??????????????? m_innerFactory.Close(span);
????????????}
????????????catch?(CommunicationException)
????????????{
??????????????? m_innerFactory.Abort();
????????????}
????????????catch?(TimeOutException)
????????????{
??????????????? m_innerFactory.Abort();
????????????}
????????????catch?(Exception)
????????????{
??????????????? m_innerFactory.Abort();
????????????????throw;
????????????}
????????}
????}
????private?void?Dispose(booling disposing)
????{
????????if?(disposing)
????????{
??????????? Close();
????????}
????}
????void?IDisposable.Dispose()
????{
??????? Dispose(true);
??????? GC.SuppressFinalize(this);
????}
}

其實,新聞中提到采用代理模式的方式與此實現相同。總之,萬變不離其宗,所有替代方案的設計本質都是對冗長的try/catch/finally的一次包裝,從而有效地實現重用,保證系統的安全、性能與穩定性。








本文轉自wayfarer51CTO博客,原文鏈接:http://blog.51cto.com/wayfarer/280084,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的WCF中的Dispose的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。