GC.KeepAlive(Object) Metodo

Definizione

Fa riferimento all'oggetto specificato, rendendolo inadatto per il Garbage Collection dall'inizio della routine corrente fino al momento in cui viene chiamato il metodo.

public static void KeepAlive (object obj);
public static void KeepAlive (object? obj);

Parametri

obj
Object

Oggetto a cui fare riferimento.

Esempio

Nell'esempio di codice seguente viene creato un oggetto all'inizio del relativo Main metodo e non si fa di nuovo riferimento all'oggetto fino alla fine, quando viene chiamato il KeepAlive metodo . L'oggetto persiste per la durata di 30 secondi del Main metodo, nonostante le chiamate ai Collect metodi e WaitForPendingFinalizers .

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();
    }
}

Commenti

Lo scopo del KeepAlive metodo è garantire l'esistenza di un riferimento a un oggetto a rischio di essere recuperato prematuramente dal Garbage Collector. Uno scenario comune in cui ciò può verificarsi è quando non sono presenti riferimenti all'oggetto nel codice gestito o nei dati, ma l'oggetto è ancora in uso in codice non gestito, ad esempio API di Windows, DLL non gestite o metodi che usano COM.

Questo metodo fa riferimento al obj parametro , rendendo l'oggetto non idoneo per l'operazione di Garbage Collection dall'inizio della routine al punto, nell'ordine di esecuzione, in cui viene chiamato questo metodo. Codificare questo metodo alla fine, non all'inizio, dell'intervallo di istruzioni in cui obj deve essere disponibile.

Il KeepAlive metodo non esegue alcuna operazione e non produce effetti collaterali diversi dall'estensione della durata dell'oggetto passato come parametro.

Si applica a

Prodotto Versioni
.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
.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