1. 程式人生 > WINDOWS開發 >C# 託管資源與非託管資源(參考七)

C# 託管資源與非託管資源(參考七)

本文轉自:https://docs.microsoft.com/zh-cn/dotnet/api/system.gc.suppressfinalize?redirectedfrom=MSDN&view=netframework-4.8#System_GC_SuppressFinalize_System_Object_

請求公共語言執行時不要呼叫指定物件的終結器。

C#
public static void SuppressFinalize (object obj);

引數

obj
Object

不得執行其終結器的物件。

例外

ArgumentNullException

objnull

示例

下面的示例演示如何在資源類中使用SuppressFinalize方法,以防止呼叫冗餘垃圾回收。該示例使用dispose 模式來釋放託管資源(即實現IDisposable的物件)和非託管資源。

C#
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

public class ConsoleMonitor : IDisposable
{
   const int STD_INPUT_HANDLE = -10;
   const int STD_OUTPUT_HANDLE = -11;
   const int STD_ERROR_HANDLE = -12;

   [DllImport("kernel32.dll",SetLastError = true)]
   static extern IntPtr GetStdHandle(int nStdHandle); 

   [DllImport("kernel32.dll",SetLastError = true)]
   static extern bool WriteConsole(IntPtr hConsoleOutput,string lpBuffer,uint nNumberOfCharsToWrite,out uint lpNumberOfCharsWritten,IntPtr lpReserved);   

   [DllImport("kernel32.dll",SetLastError = true)]
   static extern bool CloseHandle(IntPtr handle); 
                    
   private bool disposed = false;
   private IntPtr handle;
   private Component component;
   
   public ConsoleMonitor()
   {
      handle = GetStdHandle(STD_OUTPUT_HANDLE);
      if (handle == IntPtr.Zero)
         throw new InvalidOperationException("A console handle is not available.");

      component = new Component();
      
      string output = "The ConsoleMonitor class constructor.\n";
      uint written = 0;
      WriteConsole(handle,(uint) output.Length,out written,IntPtr.Zero);
   }

   // The destructor calls Object.Finalize.
   ~ConsoleMonitor()
   {
      if (handle != IntPtr.Zero) {
         string output = "The ConsoleMonitor finalizer.\n";
         uint written = 0;
         WriteConsole(handle,IntPtr.Zero);
      }
      else {     
         Console.Error.WriteLine("Object finalization.");
      }
      // Call Dispose with disposing = false.
      Dispose(false);
   }

   public void Write()
   {
      string output = "The Write method.\n";
      uint written = 0;
      WriteConsole(handle,IntPtr.Zero);
   }

   public void Dispose()
   {
      string output = "The Dispose method.\n";
      uint written = 0;
      WriteConsole(handle,IntPtr.Zero);

      Dispose(true);
      GC.SuppressFinalize(this); 
   }

   private void Dispose(bool disposing)
   {
      string output = String.Format("The Dispose({0}) method.\n",disposing);
      uint written = 0;
      WriteConsole(handle,IntPtr.Zero);

      // Execute if resources have not already been disposed.
      if (! disposed) {
         // If the call is from Dispose,free managed resources.
         if (disposing) {
            Console.Error.WriteLine("Disposing of managed resources.");
            if (component != null)
               component.Dispose();
         }
         // Free unmanaged resources.
         output = "Disposing of unmanaged resources.";
         WriteConsole(handle,IntPtr.Zero);
         
         if (handle != IntPtr.Zero) {
            if (! CloseHandle(handle))
               Console.Error.WriteLine("Handle cannot be closed."); 
         }      
      }
      disposed = true;
   }
}

public class Example
{
   public static void Main()
   {
      Console.WriteLine("ConsoleMonitor instance....");
      ConsoleMonitor monitor = new ConsoleMonitor();
      monitor.Write();
      monitor.Dispose();
   }
}
// If the monitor.Dispose method is not called,the example displays the following output:
//       ConsoleMonitor instance....
//       The ConsoleMonitor class constructor.
//       The Write method.
//       The ConsoleMonitor finalizer.
//       The Dispose(False) method.
//       Disposing of unmanaged resources.
//       
// If the monitor.Dispose method is called,the example displays the following output:
//       ConsoleMonitor instance....
//       The ConsoleMonitor class constructor.
//       The Write method.
//       The Dispose method.
//       The Dispose(True) method.
//       Disposing of managed resources.
//       Disposing of unmanaged resources.

註解

此方法設定obj的物件標頭中的一個位,執行時在呼叫終結器時進行檢查。Object.Finalize方法表示的終結器用於在對物件進行垃圾回收之前釋放非託管資源。如果obj沒有終結器或 GC 已向終結器執行緒發出執行終結器的訊號,則對SuppressFinalize方法的呼叫不起作用。

實現IDisposable介面的物件可以從物件的IDisposable.Dispose實現中呼叫此方法,以防止垃圾回收器在不需要的物件上呼叫Object.Finalize通常,這樣做是為了防止終結器釋放已由IDisposable.Dispose實現釋放的非託管資源。

適用於

.NET

5 Preview 1

.NET Core

3.13.02.22.12.01.11.0

.NET Framework

4.84.7.24.7.14.74.6.24.6.14.64.5.24.5.14.54.03.53.02.01.1

.NET Standard

2.12.01.61.51.41.31.21.11.0

UWP

10.0

Xamarin.Android

7.1

Xamarin.iOS

10.8

Xamarin.Mac

3.0