當前位置:
首頁 > 知識 > ASP.NET Core 四種釋放 IDisposable 對象的方法

ASP.NET Core 四種釋放 IDisposable 對象的方法

IDisposable 介面是.NET中最常用的介面之一。當類型包含非託管資源的引用,比如窗口句柄、文件或網路通信,可以實現IDisposable介面。垃圾收集器自動釋放託管(即.NET)對象的內存,但不知道如何處理非託管資源。通過實現IDisposable介面,您可以在類被釋放時正確地清理這些資源。

這篇文章介紹了在ASP.NET Core應用程序中可以用於處理釋放資源的一些方法,特別是在使用內置的依賴注入容器時。

為了達到這篇文章的目的,我在示例中使用下面實現了IDisposable介面的類。為了達到我們演示的目的,只需要將日誌輸出到控制台,而不需要做任何實際的清理工作。

現在來看看我們的方案。

最簡單的方法 - using語法

在代碼中使用using語句塊釋放一個IDisposable對象是一種最普通的方法:

ASP.NET Core 四種釋放 IDisposable 對象的方法

使用using語句塊的方式,無論是否拋出異常,都能確保Dispose方法可以正常的執行。如果需要,您也可以使用try- finally語句塊的方式:

ASP.NET Core 四種釋放 IDisposable 對象的方法

您會發現通常在使用文件或流(在短暫的某一範圍內)等會用此模式。不幸的是,有時不一定符合這種情況,您可能需要在其它的地方釋放該對象。根據您的真實情況,還可以使用一些其它的方式。


注意: 只要有可能,最好的做法就是將它們在創建的使用範圍內釋放。這將有助於防止應用程序中的內存泄漏和意外的文件鎖,或者對象意外地未釋放。

在請求結束時釋放 - 使用RegisterForDispose當您在ASP.NET Core或任何Web應用程序工作時,將對象的使用範圍限定為單個請求是非常常見的。也就是說,任何您在請求時創建的對像,在請求完成時釋放該對象。

有很多方法可以做到這一點。最常見的方法是在利用依賴容器(我馬上就會講到),但有時候不可能,因為您可能需要在代碼中手動創建IDisposable對象。

如果您手動創建一個IDisposable實例,則可以將該實例註冊到HttpContext中,以便在請求結束時,該實例被自動釋放。只需將實例傳遞給HttpContext.Response.RegisterForDispose方法:

ASP.NET Core 四種釋放 IDisposable 對象的方法

在這個例子中,我在HomeController的構造函數中創建Disposable對象,然後在action方法中註冊它。這種設計有點做作,但至少展示了這種機制。

如果執行此action方法,您將看到以下內容:

ASP.NET Core 四種釋放 IDisposable 對象的方法

HttpContext負責為我們釋放我們創建的對象!


警告: 我在action方法中註冊實例,而不是構造方法,是因為在構造函數中HttpContext為null!

在您的代碼中,RegisterForDispose對處理創建的服務很有用。但是鑒於Dispose模式僅適用於使用非託管資源的類,您可能會發現,通常情況下,您的IDisposable類被封裝在使用依賴容器註冊的服務中。

正如 Mark Rendle 指出的那樣,Controller本身也將在請求結束時釋放,因此您可以使用該機制來處理您創建的任何對象。

自動釋放服務 - 利用內置依賴容器

ASP.NET Core附帶一個簡單的內置依賴容器,您可以使用「Transient」,「Scoped」或「Singleton」註冊您的服務。你可以在這裡了解更多,所以我假設您已經知道如何使用它來註冊您的服務。


請注意,本文僅討論內置容器 - 第三方容器可能有其它關於自動處理服務的規則。

內置容器可以填充任何服務創建的依賴項,它將實現了IDisposable介面的對象,將在適當的時候由容器釋放。因此TransientScoped實例將在請求結束時(或更準確地說,在範圍結束時),Singleton
實例在應用程序被關閉釋放,並且ServiceProvider自身也會被釋放。

這意味著只要您不提供具體的實例,提供者將釋放您註冊的任何服務。例如,我將創建一些可釋放類:

ASP.NET Core 四種釋放 IDisposable 對象的方法

Startup.ConfigureServices方法以不同的方式註冊它們。我將這樣註冊:

TransientCreatedByContainer - transient

ScopedCreatedByFactory- scoped,使用lambda函數作為工廠

SingletonCreatedByContainer - singleton

SingletonAddedManually - singleton,傳遞具體的實例對象

ASP.NET Core 四種釋放 IDisposable 對象的方法

最後,我將在HomeController中依次傳每個實例,因此依賴容器將根據需要創建/注入實例:

ASP.NET Core 四種釋放 IDisposable 對象的方法

當我運行應用程序,點擊主頁,然後停止應用程序,我將得到以下輸出:

ASP.NET Core 四種釋放 IDisposable 對象的方法

這裡有幾件事要注意:

SingletonAddedManually 是在Web主機完成設置之前創建的,因此,在日誌開始之前,它將寫入控制台

SingletonCreatedByContainer 在我們關閉服務之後被釋放

SingletonAddedManually從來沒有釋放,因為我們提供了一個具體的實例!


請注意,由依賴容器創建的對象被釋放的行為只適用於ASP.NET Core 1.1及更高版本。在ASP.NET Core 1.0中,所有容器註冊的對象都會被釋放。

讓容器幫您處理IDisposable對象顯然很方便,特別是您可能已經在註冊您的服務!這裡唯一的需要注意的是您需要釋放您自己創建的對象。正如我剛才所說,如果可能,您應該盡量使用using語法,但這並不總是可能的。幸運的是,ASP.NET Core 應用程序的生命周期提供了機制,所以在應用程序關閉時可以進行一些清理。

應用程序結束時釋放 - 利用 IApplicationLifetime 事件

ASP.NET Core公開了一個稱為 IApplicationLifetime 的介面,可用於在應用程序啟動或關閉時執行代碼:

ASP.NET Core 四種釋放 IDisposable 對象的方法

您可以將其注入您的Startup類(或其它類),並註冊您需要的事件。擴展前面的例子,我們在 Startup.cs 的Configure方法中注入IApplicationLifetimeSingletonAddedManually實例的單例:

ASP.NET Core 四種釋放 IDisposable 對象的方法

我創建了一個簡單的幫助方法,傳入SingletonAddedManually的實例,將其轉換為IDisposable並將其釋放。該幫助方法被註冊到類型是CancellationTokenApplicationStopping屬性中,當關閉應用程序時,該方法被觸發。

如果我們再次運行應用程序,通過此額外的註冊,您可以看到該SingletonAddedManually實例現在已被釋放,就在應用程序關閉之後觸發。

ASP.NET Core 四種釋放 IDisposable 對象的方法

概要

您有四種不同的方法來處理您的IDisposable對象。只要有可能,您應該使用using語法,或者讓依賴容器為您釋放對象。對於不可能的情況,ASP.NET Core提供了兩種可以掛接的機制:RegisterForDispose和IApplicationLifetime。

文章來自博客園,轉載註明出處!

找工作太難?是你水平不行,我們來幫你提高!

http://www.ujiuye.com/zt/jyfc/?wt.bd=fq37300j

竟然有人賠本辦求學夏令營?

http://www.ujiuye.com/zt/qgsqxly/?wt.bd=fq37300j

交流群:345648424

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT優就業 的精彩文章:

測試|只有聰明人才看得出來的6張圖, 你能看出來嗎?

TAG:IT優就業 |

您可能感興趣

ASP.NET Web Forms ArrayList 對象
ASP FileSystemObject 對象
ASP Response 對象
XML DOM-ProcessingInstruction 對象
ASP Application 對象
ES6 Promise 對象
XML DOM-DocumentImplementation 對象
ASP Folder 對象
XML DOM Parse Error 對象
使用Tensorflow Object Detection API實現對象檢測
Supreme 的下個聯名對象是 D&G?mastermind JAPAN x ZAKU 要來了
ASP Session 對象
Web Pages WebSecurity 對象
Web Pages Database 對象
A$AP Rocky 新專輯曲目曝光?合作對象包含 Snoop Dogg、Kid Cudi、T.I. 等人
XML DOM-NamedNodeMap 對象
Chrome 66 新特性:CSS 類型對象模型,非同步剪貼板 API,AudioWorklet,等
不打開文件獲取名稱。Excel VBA Application對象GetOpenFilename方法教程
ASP Drive 對象
Supreme 的下一個奢華品牌合作對象是 Dolce&Gabanna?