英語で読む

次の方法で共有


GC.SuppressFinalize(Object) メソッド

定義

指定したオブジェクトに対してファイナライザーを呼び出さないよう共通言語ランタイムに要求します。

C#
public static void SuppressFinalize(object obj);

パラメーター

obj
Object

実行すべきではないファイナライザーを持つオブジェクト。

例外

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, output, (uint) output.Length, out written, IntPtr.Zero);
   }

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

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

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

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

   private void Dispose(bool disposing)
   {
      string output = String.Format("The Dispose({0}) method.\n", disposing);
      uint written = 0;
      WriteConsole(handle, output, (uint) output.Length, out written, 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, output, (uint) output.Length, out written, 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 によって表されるファイナライザーは、オブジェクトがガベージ コレクションされる前に、アンマネージ リソースを解放します。 ファイナライザーがない場合、または GC がファイナライザースレッドにファイナライザーを実行するように既に通知している場合 obj 、メソッドの SuppressFinalize 呼び出しは無効です。

IDisposableインターフェイスを実装するオブジェクトは、IDisposable.Disposeメソッド内でこのメソッドを呼び出すことができます。そのようにして、ガベージ コレクターが不必要になObject.Finalizeを呼び出すことを避けられます。 通常、これは、IDisposable.Disposeによってすでに解放されているアンマネージ リソースをファイナライザーが解放しようとするのを防ぐために実装されます。

適用対象

製品 バージョン
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

こちらもご覧ください