您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“C# Dispose方法是如何實現(xiàn)的”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
C# Dispose方法的理解是什么呢?類型的Dispose方法應(yīng)釋放它擁有的所有資源。它還應(yīng)該通過調(diào)用其父類型的Dispose方法釋放其基類型擁有的所有資源。該父類型的 Dispose 方法應(yīng)該釋放它擁有的所有資源并同樣也調(diào)用其父類型的 Dispose 方法,從而在整個基類型層次結(jié)構(gòu)中傳播此模式。若要確保始終正確地清理資源,Dispose 方法應(yīng)該可以被多次調(diào)用而不引發(fā)任何異常。
Dispose 方法應(yīng)該為它處置的對象調(diào)用 GC.SuppressFinalize 方法。如果對象當(dāng)前在終止隊列中,GC.SuppressFinalize 防止其 Finalize 方法被調(diào)用。請記住,執(zhí)行 Finalize 方法會大大減損性能。如果您的 Dispose 方法已經(jīng)完成了清理對象的工作,那么垃圾回收器就不必再調(diào)用對象的 Finalize 方法。
C# Dispose方法的實現(xiàn)時注意
為 System.GC.KeepAlive(System.Object) 方法提供的代碼示例演示了強(qiáng)行垃圾回收如何在回收對象的成員仍在執(zhí)行時引起終結(jié)器運(yùn)行。在較長的Dispose方法末尾***調(diào)用KeepAlive方法。
下面的代碼示例旨在闡釋用于為封裝了非托管資源的類實現(xiàn)Dispose方法的建議設(shè)計模式。整個 .NET Framework 中都實現(xiàn)了此模式。
資源類通常是從復(fù)雜的本機(jī)類或 API 派生的,而且必須進(jìn)行相應(yīng)的自定義。使用這一代碼模式作為創(chuàng)建資源類的一個起始點(diǎn),并根據(jù)封裝的資源提供必要的自定義。不能編譯該示例,也不能將其直接用于應(yīng)用程序。
在此示例中,基類 BaseResource 實現(xiàn)可由該類的用戶調(diào)用的公共 Dispose 方法。而該方法又調(diào)用 virtual Dispose(bool disposing) 方法(Visual Basic 中為 virtual Dispose(disposing As Boolean))。根據(jù)調(diào)用方的標(biāo)識傳遞 true 或 false。以虛 Dispose 方法為對象執(zhí)行適當(dāng)?shù)那謇泶a。
Dispose(bool disposing) 以兩種截然不同的方案執(zhí)行。如果 disposing 等于 true,則該方法已由用戶的代碼直接調(diào)用或間接調(diào)用,并且可釋放托管資源和非托管資源。如果 disposing 等于 false,則該方法已由運(yùn)行庫從終結(jié)器內(nèi)部調(diào)用,并且只能釋放非托管資源。因為終結(jié)器不會以任意特定的順序執(zhí)行,所以當(dāng)對象正在執(zhí)行其終止代碼時,不應(yīng)引用其他對象。如果正在執(zhí)行的終結(jié)器引用了另一個已經(jīng)終止的對象,則該正在執(zhí)行的終結(jié)器將失敗。
基類提供的 Finalize 方法或析構(gòu)函數(shù)在未能調(diào)用 Dispose 的情況下充當(dāng)防護(hù)措施。Finalize 方法調(diào)用帶有參數(shù)的 Dispose 方法,同時傳遞 false。不應(yīng)在 Finalize 方法內(nèi)重新創(chuàng)建 Dispose 清理代碼。調(diào)用 Dispose(false) 可以優(yōu)化代碼的可讀性和可維護(hù)性。
類 MyResourceWrapper 闡釋如何使用 Dispose 從實現(xiàn)資源管理的類派生。MyResourceWrapper 重寫 virtual Dispose(bool disposing) 方法并為其創(chuàng)建的托管和非托管資源提供清理代碼。MyResourceWrapper 還對其基類 BaseResource 調(diào)用 Dispose 以確保其基類能夠適當(dāng)?shù)剡M(jìn)行清理。請注意,派生類 MyResourceWrapper 沒有不帶參數(shù)的 Finalize 方法或 Dispose 方法,因為這兩個方法從基類 BaseResource 繼承這些參數(shù)。
C# Dispose方法的實現(xiàn)時注意
此示例中的 protected Dispose(bool disposing) 方法不強(qiáng)制線程安全,因為無法從用戶線程和終結(jié)器線程同時調(diào)用該方法。另外,使用 BaseResource 的客戶端應(yīng)用程序應(yīng)從不允許多個用戶線程同時調(diào)用 protected Dispose(bool disposing) 方法。應(yīng)用程序或類庫的設(shè)計原則為:應(yīng)用程序或類庫應(yīng)只允許一個線程擁有資源的生存期,并且應(yīng)在不再需要資源時調(diào)用 Dispose。根據(jù)資源的不同,在處置資源時進(jìn)行異步線程訪問可能會帶來安全風(fēng)險。開發(fā)人員應(yīng)仔細(xì)檢查自己的代碼,以確定***的方法來強(qiáng)制線程安全
C# Dispose方法的實現(xiàn)實例
// Design pattern for the base class. // By implementing IDisposable, you are announcing that instances // of this type allocate scarce resources. public class BaseResource: IDisposable { // Pointer to an external unmanaged resource. private IntPtr handle; // Other managed resource this class uses. private Component Components; // Track whether Dispose has been called. private bool disposed = false; // Constructor for the BaseResource object. public BaseResource() { // Insert appropriate constructor code here. } // Implement IDisposable. // Do not make this method virtual. // A derived class should not be able to override this method. public void Dispose() { Dispose(true); // Take yourself off the Finalization queue // to prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); } // Dispose(bool disposing) executes in two distinct scenarios. // If disposing equals true, the method has been called directly // or indirectly by a user's code. Managed and unmanaged resources // can be disposed. // If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. protected virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if(!this.disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if(disposing) { // Dispose managed resources. Components.Dispose(); } // Release unmanaged resources. If disposing is false, // only the following code is executed. CloseHandle(handle); handle = IntPtr.Zero; // Note that this is not thread safe. // Another thread could start disposing the object // after the managed resources are disposed, // but before the disposed flag is set to true. // If thread safety is necessary, it must be // implemented by the client. } disposed = true; } // Use C# destructor syntax for finalization code. // This destructor will run only if the Dispose method // does not get called. // It gives your base class the opportunity to finalize. // Do not provide destructors in types derived from this class. ~BaseResource() { // Do not re-create Dispose clean-up code here. // Calling Dispose(false) is optimal in terms of // readability and maintainability. Dispose(false); } // Allow your Dispose method to be called multiple times, // but throw an exception if the object has been disposed. // Whenever you do something with this class, // check to see if it has been disposed. public void DoSomething() { if(this.disposed) { throw new ObjectDisposedException(); } } } // Design pattern for a derived class. // Note that this derived class inherently implements the // IDisposable interface because it is implemented in the base class. public class MyResourceWrapper: BaseResource { // A managed resource that you add in this derived class. private ManagedResource addedManaged; // A native unmanaged resource that you add in this derived class. private NativeResource addedNative; private bool disposed = false; // Constructor for this object. public MyResourceWrapper() { // Insert appropriate constructor code here. } protected override void Dispose(bool disposing) { if(!this.disposed) { try { if(disposing) { // Release the managed resources you added in // this derived class here. addedManaged.Dispose(); } // Release the native unmanaged resources you added // in this derived class here. CloseHandle(addedNative); this.disposed = true; } finally { // Call Dispose on your base class. base.Dispose(disposing); } } } } // This derived class does not have a Finalize method // or a Dispose method without parameters because it inherits // them from the base class.
“C# Dispose方法是如何實現(xiàn)的”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。