GC.SuppressFinalize(Object) メソッド

定義

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

public:
 static void SuppressFinalize(System::Object ^ obj);
public static void SuppressFinalize (object obj);
static member SuppressFinalize : obj -> unit
Public Shared Sub SuppressFinalize (obj As Object)

パラメーター

obj
Object

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

例外

objnullです。

次の例では、冗長なガベージ コレクション呼び出しを防ぐため、リソース クラスにおいてSuppressFinalizeを使用する方法を示します。 dispose パターンを用いて、マネージ リソース(IDisposableを実装するオブジェクト)とアンマネージ リソースの両方を解放しています。

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.
open System
open System.ComponentModel
open System.Runtime.InteropServices

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

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

[<DllImport("kernel32.dll", SetLastError = true)>]
extern bool CloseHandle(IntPtr handle)

type ConsoleMonitor() =
    let STD_INPUT_HANDLE = -10
    let STD_OUTPUT_HANDLE = -11
    let STD_ERROR_HANDLE = -12

    let handle =
        let h = GetStdHandle STD_OUTPUT_HANDLE
        if h = IntPtr.Zero then
            raise (InvalidOperationException "A console handle is not available.")
        else
            h

    let comp = new Component()
    let output = "The ConsoleMonitor class constructor.\n"
    let mutable disposed = false
    let mutable written = 0u
    do
        WriteConsole(handle, output, uint output.Length, &written, IntPtr.Zero)
        |> ignore

    // The finalizer represents Object.Finalize override.
    override this.Finalize() =
        if handle <> IntPtr.Zero then
            let output = "The ConsoleMonitor finalizer.\n"
            let mutable written = 0u
            WriteConsole(handle, output, uint output.Length, &written, IntPtr.Zero)
            |> ignore
        else
            eprintfn "Object finalization."
        this.Dispose false

    member _.Write() =
        let output = "The Write method.\n"
        let mutable written = 0u

        WriteConsole(handle, output, uint output.Length, &written, IntPtr.Zero)
        |> ignore

    member _.Dispose(disposing: bool) =
        let output = $"The Dispose({disposing}) method.\n"
        let mutable written = 0u

        WriteConsole(handle, output, uint output.Length, &written, IntPtr.Zero)
        |> ignore

        // Execute if resources have not already been disposed.
        if not disposed then
            // If the call is from Dispose, free managed resources.
            if disposing then
                eprintfn "Disposing of managed resources."
                if comp <> null then comp.Dispose()
            // Free unmanaged resources.
            let output = "Disposing of unmanaged resources."

            WriteConsole(handle, output, uint output.Length, &written, IntPtr.Zero)
            |> ignore

            if handle <> IntPtr.Zero then
                if not (CloseHandle handle) then
                    eprintfn "Handle cannot be closed."

        disposed <- true

    member this.Dispose() =
        let output = "The Dispose method.\n"
        let mutable written = 0u

        WriteConsole(handle, output, uint output.Length, &written, IntPtr.Zero)
        |> ignore

        this.Dispose true
        GC.SuppressFinalize this

    interface IDisposable with
        member this.Dispose() = this.Dispose()

printfn "ConsoleMonitor instance...."
let 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.
Imports System.ComponentModel
Imports System.Runtime.InteropServices

Public Class ConsoleMonitor
   Private Const STD_INPUT_HANDLE As Integer = -10
   Private Const STD_OUTPUT_HANDLE As Integer = -11
   Private Const STD_ERROR_HANDLE As Integer = -12

   Private Declare Function GetStdHandle Lib "kernel32" _
                            (nStdHandle As Integer) As IntPtr

   Private Declare Function WriteConsole Lib "kernel32" _
                            Alias "WriteConsoleA" _
                            (hConsoleOutput As IntPtr, lpBuffer As String,
                            nNumberOfCharsToWrite As UInteger,
                            ByRef lpNumberOfCharsWritten As UInteger,
                            lpReserved As IntPtr) As Boolean

   Private Declare Function CloseHandle Lib "kernel32" _
                           (handle As IntPtr) As Boolean

   Private disposed As Boolean = False
   Private handle As IntPtr
   Private component As Component

   Public Sub New()
      handle = GetStdHandle(STD_OUTPUT_HANDLE)
      If handle = IntPtr.Zero Then
         Throw New InvalidOperationException("A console handle is not available.")
      End If

      component = new Component()

      Dim output As String = "The ConsoleMonitor class constructor." + vbCrLf
      Dim written As UInteger = 0
      WriteConsole(handle, output, CUInt(output.Length), written, IntPtr.Zero)
   End Sub

   Protected Overrides Sub Finalize()
      If handle <> IntPtr.Zero Then
         Dim output As String = "The ConsoleMonitor finalizer." + vbCrLf
         Dim written As UInteger = 0
         WriteConsole(handle, output, CUInt(output.Length), written, IntPtr.Zero)
      Else
         Console.Error.WriteLine("Object finalization.")
      End If
      Dispose(disposing:=False)
   End Sub

   Public Sub Write()
      Dim output As String = "The Write method." + vbCrLf
      Dim written As UInteger = 0
      WriteConsole(handle, output, CUInt(output.Length), written, IntPtr.Zero)
   End Sub

   Public Sub Dispose()
      Dim output As String =  "The Dispose method." + vbCrLf
      Dim written As UInteger = 0
      WriteConsole(handle, output, CUInt(output.Length), written, IntPtr.Zero)

      Dispose(disposing:=True)
      GC.SuppressFinalize(Me)
   End Sub

   Private Sub Dispose(disposing As Boolean)
      Dim output As String =  String.Format("The Dispose({0}) method.{1}",
                                            disposing, vbCrLf)
      Dim written As UInteger = 0
      WriteConsole(handle, output, CUInt(output.Length), written, IntPtr.Zero)

      ' Execute if resources have not already been disposed.
      If Not disposed Then
         ' If the call is from Dispose, free managed resources.
         If disposing Then
            Console.Error.WriteLine("Disposing of managed resources.")
            If component IsNot Nothing Then component.Dispose()
         End If
         ' Free unmanaged resources.
         output = "Disposing of unmanaged resources."
         WriteConsole(handle, output, CUInt(output.Length), written, IntPtr.Zero)

         If handle <> IntPtr.Zero Then
            If Not CloseHandle(handle) Then
               Console.Error.WriteLine("Handle cannot be closed.")
            End If
         End If
      End If
      disposed = True
   End Sub
End Class

Module Example
   Public Sub Main()
      Console.WriteLine("ConsoleMonitor instance....")
      Dim monitor As New ConsoleMonitor
      monitor.Write()
      monitor.Dispose()
   End Sub
End Module
' 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によってすでに解放されているアンマネージ リソースをファイナライザーが解放しようとするのを防ぐために実装されます。

適用対象

こちらもご覧ください