英語で読む

次の方法で共有


GC.KeepAlive(Object) メソッド

定義

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

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

パラメーター

obj
Object

参照するオブジェクト。

次のコード例では、メソッドの Main 先頭に オブジェクトを作成し、 メソッドが呼び出されるまで KeepAlive オブジェクトを再度参照しません。 オブジェクトは、 メソッドと WaitForPendingFinalizers メソッドの呼び出しCollectにもかかわらず、 メソッドの Main 30 秒間保持されます。

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

注釈

メソッドの KeepAlive 目的は、ガベージ コレクターによって途中で再利用されるリスクがあるオブジェクトへの参照が存在することを確認することです。 これが発生する可能性がある一般的なシナリオは、マネージド コードまたはデータ内のオブジェクトへの参照がないが、オブジェクトが Windows API、アンマネージ DLL、COM を使用するメソッドなどのアンマネージ コードで引き続き使用されている場合です。

このメソッドは パラメーターを obj 参照し、そのオブジェクトは、ルーチンの先頭からポイントまでのガベージ コレクションの対象外となり、実行順序でこのメソッドが呼び出されます。 このメソッドは、使用できる必要がある命令 obj の範囲の先頭ではなく、最後にコーディングします。

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

適用対象

製品 バージョン
.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