溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C# Dispose方法是如何實現(xiàn)的

發(fā)布時間:2021-06-16 14:51:52 來源:億速云 閱讀:277 作者:chen 欄目:編程語言

本篇內(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ì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(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)容。

AI