Export (0) Print
Expand All

GC.KeepAlive Method

References the specified object, making it ineligible for garbage collection from the start of the current routine to the point where this method is called.

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

Parameters

obj
The object to reference.

Remarks

The purpose of the KeepAlive method is to ensure the existence of a reference to an object that is at risk of being prematurely reclaimed by the garbage collector. A common scenario where this might happen is when there are no references to the object in managed code or data but the object is still in use in unmanaged code, such as Win32 APIs, unmanaged DLLs, or methods using COM.

This method references obj, making that object ineligible for garbage collection from the start of the routine to the point, in execution order, where this method is called. Code this method at the end, not the beginning, of the range of instructions where obj must be available.

The KeepAlive method performs no operation and produces no side effect other than extending the lifetime of the object passed in as a parameter.

Example

[Visual Basic] 
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] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family, .NET Compact Framework, Common Language Infrastructure (CLI) Standard

See Also

GC Class | GC Members | System Namespace

Show:
© 2014 Microsoft