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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

WCF中的Dispose

發(fā)布時(shí)間:2024/1/17 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WCF中的Dispose 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

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

微軟推薦的最佳實(shí)踐是拋棄using語(yǔ)句,轉(zhuǎn)而利用try/catch(/finally)語(yǔ)句。它要求在try語(yǔ)句中調(diào)用Close()方法,而在catch中調(diào)用Abort()方法。在新聞中已經(jīng)說(shuō)明了Close()與Abort()方法的區(qū)別,即后者可以強(qiáng)制地關(guān)閉客戶端,包括關(guān)閉客戶端連接,釋放資源。由于Close()方法可能會(huì)拋出CommunicationException和TimeoutException異常,通常的客戶端代碼應(yīng)該是這樣:

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

在最后增加對(duì)Exception異常的捕獲很有必要,因?yàn)槲覀儾恢繡lose()方法會(huì)否拋出某些不可預(yù)知的異常,例如OutOfMemoryException等。新聞中提到Steve Smith的方法其實(shí)就是對(duì)這段冗長(zhǎng)代碼的封裝,封裝方式是采用擴(kuò)展方法,擴(kuò)展的類型為ICommunicationObject。這是因?yàn)樗械目蛻舳藢?duì)象都實(shí)現(xiàn)了ICommunicationObject接口。以下是Steve Smith的擴(kuò)展方法代碼:

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;
????????}
????}
}

?利用該擴(kuò)展方法,在本應(yīng)調(diào)用Close()方法的地方,代替為CloseConnection()方法,就可以避免寫冗長(zhǎng)的catch代碼。而使用Lambda表達(dá)式的方式可以說(shuō)是獨(dú)辟蹊徑,使用起來(lái)與using語(yǔ)法大致接近。實(shí)現(xiàn)方法是定義一個(gè)靜態(tài)方法,并接受一個(gè)ICommunicationObject對(duì)象與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;
????????}
????}
}

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

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

?還有一種方法是定義一個(gè)自己的ChannelFactory,讓其實(shí)現(xiàn)IDisposable接口,并作為ChannelFactory的Wrapper類。在該類中定義Close()和Dispose()方法時(shí),考慮到異常拋出的情況,并在異常拋出時(shí)調(diào)用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);
????}
}

其實(shí),新聞中提到采用代理模式的方式與此實(shí)現(xiàn)相同。總之,萬(wàn)變不離其宗,所有替代方案的設(shè)計(jì)本質(zhì)都是對(duì)冗長(zhǎng)的try/catch/finally的一次包裝,從而有效地實(shí)現(xiàn)重用,保證系統(tǒng)的安全、性能與穩(wěn)定性。








本文轉(zhuǎn)自wayfarer51CTO博客,原文鏈接:http://blog.51cto.com/wayfarer/280084,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者

總結(jié)

以上是生活随笔為你收集整理的WCF中的Dispose的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。