GC.KeepAlive メソッド

指定したオブジェクトを参照し、現在のルーチンの開始時からこのメソッドが呼び出される時点までの間、そのオブジェクトをガベージ コレクションの対象から外します。

Public Shared Sub KeepAlive( _
   ByVal obj As Object _)
[C#]
public static void KeepAlive(objectobj);
[C++]
public: static void KeepAlive(Object* obj);
[JScript]
public static function KeepAlive(
   obj : Object);

パラメータ

  • obj
    参照するオブジェクト。

解説

KeepAlive メソッドの目的は、ガベージ コレクタにより時期尚早に収集されるおそれがあるオブジェクトが確実に参照されるようにすることです。このような危険が起こり得るのは、マネージ コードまたはマネージ データではオブジェクトが参照されていないが、そのオブジェクトが、Win32 API、アンマネージ DLL、COM などのアンマネージ コードで依然として使用されている場合です。

このメソッドは、 obj オブジェクトを参照し、ルーチンの開始時からこのメソッドが呼び出される時点までの間、そのオブジェクトをガベージ コレクションの対象から外します。このメソッドのコードは、 obj を使用可能にする必要がある命令の範囲の最初ではなく最後に作成します。

KeepAlive メソッドでは何も実行されず、パラメータとして渡されるオブジェクトの有効期間が延長される以外に副作用は発生しません。

使用例

 
Imports System
Imports System.Threading
Imports System.Runtime.InteropServices

' A simple class that exposes two static Win32 functions.
' One is a delegate type and the other is an enumerated type.

Public Class MyWin32

   ' Declare the SetConsoleCtrlHandler function as external 
   ' and receiving a delegate.   
   <DllImport("Kernel32")> _
   Public Shared Function SetConsoleCtrlHandler(ByVal Handler As HandlerRoutine, _
         ByVal Add As Boolean) As Boolean
   End Function


   ' A delegate type to be used as the handler routine 
   ' for SetConsoleCtrlHandler.
   Delegate Function HandlerRoutine(ByVal CtrlType As CtrlTypes) As [Boolean]

   ' An enumerated type for the control messages 
   ' sent to the handler routine.

   Public Enum CtrlTypes
      CTRL_C_EVENT = 0
      CTRL_BREAK_EVENT
      CTRL_CLOSE_EVENT
      CTRL_LOGOFF_EVENT = 5
      CTRL_SHUTDOWN_EVENT
   End Enum
End Class

Public Class MyApp

   ' A private static handler function in the MyApp class.
   Shared Function Handler(ByVal CtrlType As MyWin32.CtrlTypes) As [Boolean]
      Dim message As [String] = "This message should never be seen!"

      ' A select case to handle the event type.
      Select Case CtrlType
         Case MyWin32.CtrlTypes.CTRL_C_EVENT
            message = "A CTRL_C_EVENT was raised by the user."
         Case MyWin32.CtrlTypes.CTRL_BREAK_EVENT
            message = "A CTRL_BREAK_EVENT was raised by the user."
         Case MyWin32.CtrlTypes.CTRL_CLOSE_EVENT
            message = "A CTRL_CLOSE_EVENT was raised by the user."
         Case MyWin32.CtrlTypes.CTRL_LOGOFF_EVENT
            message = "A CTRL_LOGOFF_EVENT was raised by the user."
         Case MyWin32.CtrlTypes.CTRL_SHUTDOWN_EVENT
            message = "A CTRL_SHUTDOWN_EVENT was raised by the user."
      End Select

      ' Use interop to display a message for the type of event.
      Console.WriteLine(message)

      Return True
   End Function


   Public Shared Sub Main()
      ' Use interop to set a console control handler.
      Dim hr As New MyWin32.HandlerRoutine(AddressOf Handler)
      MyWin32.SetConsoleCtrlHandler(hr, True)

      ' Give the user some time to raise a few events.
      Console.WriteLine("Waiting 30 seconds for console ctrl events...")

      ' The object hr is not referred to again.
      ' The garbage collector can detect that the object has no
      ' more managed references and might clean it up here while
      ' the unmanaged SetConsoleCtrlHandler method is still using it.      
      ' Force a garbage collection to demonstrate how the hr
      ' object will be handled.
      GC.Collect()
      GC.WaitForPendingFinalizers()
      GC.Collect()

      Thread.Sleep(30000)

      ' Display a message to the console when the unmanaged method
      ' has finished its work.
      Console.WriteLine("Finished!")

      ' Call GC.KeepAlive(hr) at this point to maintain a reference to hr. 
      ' This will prevent the garbage collector from collecting the 
      ' object during the execution of the SetConsoleCtrlHandler method.
      GC.KeepAlive(hr)
      Console.Read()
   End Sub
End Class


[C#] 
using System;
using System.Threading;
using System.Runtime.InteropServices;

// A simple class that exposes two static Win32 functions.
// One is a delegate type and the other is an enumerated type.
public class MyWin32 
{
    // Declare the SetConsoleCtrlHandler function 
    // as external and receiving a delegate.   
    [DllImport("Kernel32")] 
    public static extern Boolean SetConsoleCtrlHandler(HandlerRoutine Handler, 
        Boolean Add);

    // A delegate type to be used as the handler routine 
    // for SetConsoleCtrlHandler.
    public delegate Boolean HandlerRoutine(CtrlTypes CtrlType);

    // An enumerated type for the control messages 
    // sent to the handler routine.
    public enum CtrlTypes 
    {
        CTRL_C_EVENT = 0,
        CTRL_BREAK_EVENT,
        CTRL_CLOSE_EVENT,   
        CTRL_LOGOFF_EVENT = 5,
        CTRL_SHUTDOWN_EVENT
    }
}

public class MyApp 
{
    // A private static handler function in the MyApp class.
    static Boolean Handler(MyWin32.CtrlTypes CtrlType)
    {
        String message = "This message should never be seen!";

        // A switch to handle the event type.
        switch(CtrlType)
        {
            case MyWin32.CtrlTypes.CTRL_C_EVENT:
                message = "A CTRL_C_EVENT was raised by the user.";
                break;
            case MyWin32.CtrlTypes.CTRL_BREAK_EVENT:
                message = "A CTRL_BREAK_EVENT was raised by the user.";
                break;
            case MyWin32.CtrlTypes.CTRL_CLOSE_EVENT:   
                message = "A CTRL_CLOSE_EVENT was raised by the user.";
                break;
            case MyWin32.CtrlTypes.CTRL_LOGOFF_EVENT:
                message = "A CTRL_LOGOFF_EVENT was raised by the user.";
                break;
            case MyWin32.CtrlTypes.CTRL_SHUTDOWN_EVENT:
                message = "A CTRL_SHUTDOWN_EVENT was raised by the user.";
                break;
        }

        // Use interop to display a message for the type of event.
        Console.WriteLine(message);

        return true;
    }

    public static void Main()
    {         

        // Use interop to set a console control handler.
        MyWin32.HandlerRoutine hr = new MyWin32.HandlerRoutine(Handler);
        MyWin32.SetConsoleCtrlHandler(hr, true);

        // Give the user some time to raise a few events.
        Console.WriteLine("Waiting 30 seconds for console ctrl events...");

        // The object hr is not referred to again.
        // The garbage collector can detect that the object has no
        // more managed references and might clean it up here while
        // the unmanaged SetConsoleCtrlHandler method is still using it.      
        
        // Force a garbage collection to demonstrate how the hr
        // object will be handled.
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        
        Thread.Sleep(30000);

        // Display a message to the console when the unmanaged method
        // has finished its work.
        Console.WriteLine("Finished!");

        // Call GC.KeepAlive(hr) at this point to maintain a reference to hr. 
        // This will prevent the garbage collector from collecting the 
        // object during the execution of the SetConsoleCtrlHandler method.
        GC.KeepAlive(hr);   
        Console.Read();
    }
}

[C++] 
#using <mscorlib.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Runtime::InteropServices;

// A simple class that exposes two static Win32 functions.
// One is a delegate type and the other is an enumerated type.
public __gc class MyWin32 {
public:
   // An enumerated type for the control messages sent to the handler routine.
   __value enum CtrlTypes {
      CTRL_C_EVENT = 0,
      CTRL_BREAK_EVENT,
      CTRL_CLOSE_EVENT,
      CTRL_LOGOFF_EVENT = 5,
      CTRL_SHUTDOWN_EVENT
   };

   // A delegate type to be used as the Handler Routine for SetConsoleCtrlHandler.
   __delegate Boolean HandlerRoutine(CtrlTypes  CtrlType);

   // Declare the SetConsoleCtrlHandler function as external and receiving a delegate.
   [DllImport(S"Kernel32")]
   static Boolean SetConsoleCtrlHandler(HandlerRoutine* Handler, Boolean Add);

};

public __gc class MyApp {
   // A private static handler function in the MyApp class.
   static Boolean Handler(MyWin32::CtrlTypes CtrlType) {
      String*  message = S"This message should never be seen!";

      // A switch to handle the event type.
      switch(CtrlType) {
            case MyWin32::CtrlTypes::CTRL_C_EVENT:
               message = S"A CTRL_C_EVENT was raised by the user.";
               break;
            case MyWin32::CtrlTypes::CTRL_BREAK_EVENT:
               message = S"A CTRL_BREAK_EVENT was raised by the user.";
               break;
            case MyWin32::CtrlTypes::CTRL_CLOSE_EVENT:
               message = S"A CTRL_CLOSE_EVENT was raised by the user.";
               break;
            case MyWin32::CtrlTypes::CTRL_LOGOFF_EVENT:
               message = S"A CTRL_LOGOFF_EVENT was raised by the user.";
               break;
            case MyWin32::CtrlTypes::CTRL_SHUTDOWN_EVENT:
               message = S"A CTRL_SHUTDOWN_EVENT was raised by the user.";
               break;
      }

      // Use interop to display a message for the type of event.
      Console::WriteLine(message);

      return true;
   }
public:
   static void Test() {

      // Use interop to set a console control handler.
      MyWin32::HandlerRoutine* hr = new MyWin32::HandlerRoutine(0, Handler);
      MyWin32::SetConsoleCtrlHandler(hr, true);

      // Give the user some time to raise a few events.
      Console::WriteLine(S"Waiting 30 seconds for console ctrl events...");

      // The Object hr is not referred to again.
      // The garbage collector can detect that the object has no
      // more managed references and might clean it up here while
      // the unmanaged SetConsoleCtrlHandler method is still using it.

      // Force a garbage collection to demonstrate how the hr
      // object will be handled.
      GC::Collect();
      GC::WaitForPendingFinalizers();
      GC::Collect();

      Thread::Sleep(30000);

      // Display a message to the console when the unmanaged method
      // has finished its work.
      Console::WriteLine(S"Finished!");

      // Call GC::KeepAlive(hr) at this point to maintain a reference to hr.
      // This will prevent the garbage collector from collecting the
      // object during the execution of the SetConsoleCtrlHandler method.
      GC::KeepAlive(hr);
   }
};

int main() {
   MyApp::Test();
}

[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン 言語のフィルタ をクリックします。

必要条件

プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ, .NET Compact Framework - Windows CE .NET, Common Language Infrastructure (CLI) Standard

参照

GC クラス | GC メンバ | System 名前空間