GC.KeepAlive メソッドとは? わかりやすく解説

GC.KeepAlive メソッド

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

名前空間: System
アセンブリ: mscorlib (mscorlib.dll 内)
構文構文

解説解説
使用例使用例

このセクションには、2 つコード例含まれています。最初の例は、KeepAlive メソッド使用して積極的なガベージ コレクションを防ぐ方法示してます。2 番目の例は、長時間実行されるメソッドKeepAlive使用する方法示してます。

例 1

収集したオブジェクトメソッド実行中に積極的なガベージ コレクション発生KeepAlive メソッドによって防止するコード例次に示します

メモメモ

この例では、複数プロセッサを持つコンピュータが必要です。

この例では、テスト メソッド繰り返し呼び出すスレッド起動します。このスレッドは、Enter キーを押すまで、実行されます。既定では、このコード例では、DoWork メソッド実行されその結果Example オブジェクト作成されて、Hash プロパティ読み取られます。DoWork メソッドでは KeepAlive メソッド使用しないので、Example オブジェクトプロパティ読み取られる前に、そのオブジェクトファイナライザ実行されることがありますDoWork メソッドでは、この処理が検出されコンソール メッセージ表示されます。

引数 KeepAlive指定してこの例を実行すると、SafeDoWork メソッド実行されます。SafeDoWork メソッドは、KeepAlive メソッド呼び出す最後の行を除いて DoWork メソッドと同じです。この行によって、SafeDoWork メソッドの処理が完了するまで、Example オブジェクトが再要求されません。

引数 Trivial指定してこの例を実行すると、Trivial メソッド実行されます。このメソッドは、Hash プロパティより高速整数プロパティアクセスます。このプロパティへのアクセス速度速いため、ファイナライザ先に実行されることはほとんどありません。

Imports System
Imports System.Threading

Public Class Example
    ' The N property is very fast, because all it does is return
    ' a stored integer. Therefore the finalizer almost never runs
    ' before this property is read.
    '
    Private nValue As Integer
    
    Public ReadOnly Property
 N() As Integer 
        Get
            Return nValue
        End Get 
    End Property 

    ' The Hash property is slower because it clones an array. When
    ' KeepAlive is not used, the finalizer sometimes runs before 
    ' the Hash property value is read.
    '
    Private hashValue() As Byte
    
    Public ReadOnly Property
 Hash() As Byte() 
        Get
            Return CType(hashValue.Clone(), Byte())
        End Get 
    End Property
 
    ' The constructor initializes the property values.
    '
    Public Sub New() 
        nValue = 2

        hashValue = New Byte(19) {}
        hashValue(0) = 2
    End Sub
    
    ' The finalizer sets the N property to zero, and clears all 
    ' the elements of the array for the Hash property. The finalizer
    ' runs on a separate thread provided by the system. In some
    ' cases, the finalizer can run while a member of the Example
    ' instance is still executing.
    '
    Overloads Protected Overrides
 Sub Finalize() 
        nValue = 0
        If Not (hashValue Is
 Nothing) Then
            Array.Clear(hashValue, 0, hashValue.Length)
        End If

        MyBase.Finalize()
    End Sub

End Class

Public Class Test
    Private Shared totalCount As
 Integer = 0
    Private Shared finalizerFirstCount As
 Integer = 0
    
    ' This variable controls the thread that runs the demo.
    Private Shared running As
 Boolean = True
    
    ' The default is to run without KeepAlive.
    Private Shared kind As
 TestKind = TestKind.NoKeepAlive
    
    ' See the comment at the end of the SafeDoWork method.
    'private static bool keepAlive = false;

    ' In order to demonstrate the finalizer running first, the
    ' DoWork method must create an Example object and invoke its
    ' Hash property. If there are no other calls to members of
    ' the Example object in DoWork, garbage collection reclaims
    ' the Example object aggressively. Sometimes this means that
    ' the finalizer runs before the call to the Hash property
    ' completes. 
    Private Shared Sub DoWork()
 

        ' Count the number of times DoWork executes.
        totalCount += 1
        
        ' Create an Example object and save the value of the 
        ' Hash property. There are no more calls to members of 
        ' the object in the DoWork method, so it is available
        ' for aggressive garbage collection.
        '
        Dim ex As New Example()
        Dim res As Byte()
 = ex.Hash
        
        ' If the finalizer runs before the call to the Hash 
        ' property completes, the hashValue array might be
        ' cleared before the property value is read. The 
        ' following test detects that.
        '
        If res(0) <> 2 Then
            finalizerFirstCount += 1
            Console.WriteLine("The finalizer ran first at {0}
 iterations.", _
                totalCount)
        End If
    
    End Sub
    
    ' In the SafeDoWork method the finalizer never runs first,
    ' because of the KeepAlive at the end of the method.
    '    
    Private Shared Sub SafeDoWork()
 

        totalCount += 1
        
        ' Create an Example object and save the value of the 
        ' Hash property.
        Dim ex As New Example()
        Dim res As Byte()
 = ex.Hash
        
        ' The finalizer cannot run before the property is read,
        ' because the KeepAlive method prevents the Example object
        ' from being reclaimed by garbage collection.
        '
        If res(0) <> 2 Then
            finalizerFirstCount += 1
            Console.WriteLine("The finalizer ran first at {0}
 iterations.", _
                totalCount)
        End If
        
        GC.KeepAlive(ex)
        ' The KeepAlive method need never be executed. For example,
        ' if the keepAlive field is uncommented, the following line
        ' of code prevents the finalizer from running first, even
        ' though it is impossible for the KeepAlive method ever to
        ' be executed.
        '    if (keepAlive) GC.KeepAlive(ex);
        ' However, if the compiler detects that the KeepAlive can
        ' never be executed, as in the following line, then it will
        ' not prevent the finalizer from running first.
        '    if (false) GC.KeepAlive(ex);
    End Sub
    
    ' In the TrivialDoWork method the finalizer almost never runs
    ' first, even without a KeepAlive at the end of the method,
    ' because accessing the N property is so fast.
    '    
    Private Shared Sub TrivialDoWork()
 
        totalCount += 1
        
        ' Create an Example object and save the value of the 
        ' N property.
        Dim ex As New Example()
        Dim res As Integer
 = ex.N
        
        ' The finalizer almost never runs before the property is read
,
        ' because accessing the N property is so fast.
        '
        If res <> 2 Then
            finalizerFirstCount += 1
            Console.WriteLine("The finalizer ran first at {0}
 iterations.", _
                totalCount)
        End If
    
    End Sub
    
    Public Shared Sub Main(ByVal
 args() As String) 
        ' Check to see what command-line argument was passed.
        If args.Length <> 0 Then
            Dim arg As String
 = args(0).ToLower()
            ' The AndAlso operator prevents the second condition from
            ' being evaluated if the first condition is false.
            If (arg.Length < 10) AndAlso
 _
                (arg = "keepalive".Substring(0, arg.Length))
 Then

                kind = TestKind.KeepAlive
            End If

            If arg.Length < 8 AndAlso _
                arg = "trivial".Substring(0, arg.Length)
 Then

                kind = TestKind.Trivial
            End If
        End If
        Console.WriteLine("Test: {0}", kind)
        
        ' Create a thread to run the test.
        Dim t As New Thread(New
 ThreadStart(AddressOf ThreadProc))
        t.Start()
        
        ' The thread runs until Enter is pressed.
        Console.WriteLine("Press Enter to stop the program.")
        Console.ReadLine()
        running = False
        
        ' Wait for the thread to end.
        t.Join()
        
        Console.WriteLine("{0} iterations total; the "
 & _
            "finalizer ran first {1} times.", _
            totalCount, finalizerFirstCount)
    
    End Sub
    
    ' This method executes the selected test.
    Private Shared Sub ThreadProc()
 
        Select Case kind
            Case TestKind.KeepAlive
                While running
                    SafeDoWork()
                End While
            
            Case TestKind.Trivial
                While running
                    TrivialDoWork()
                End While
            
            Case Else
                While running
                    DoWork()
                End While
        End Select
    
    End Sub 
    
    Private Enum TestKind
        NoKeepAlive
        KeepAlive
        Trivial
    End Enum 
End Class 

' When run with the default NoKeepAlive test, on a dual-processor
'   computer, this example produces output similar to the following:
'
'Test: NoKeepAlive
'Press Enter to stop the program.
'The finalizer ran first at 21098618 iterations.
'The finalizer ran first at 33944444 iterations.
'The finalizer ran first at 35160207 iterations.
'
'53169451 iterations total; the finalizer ran first 3 times.
'
using System;
using System.Threading;

public class Example 
{
    // The N property is very fast, because all it does is return
    // a stored integer. Therefore the finalizer almost never runs
    // before this property is read.
    //
    private int nValue;
    public int N { get {
 return nValue; }}

    // The Hash property is slower because it clones an array. When
    // KeepAlive is not used, the finalizer sometimes runs before 
    // the Hash property value is read.
    //
    private byte[] hashValue;
    public byte[] Hash { get { return
 (byte[]) hashValue.Clone(); }}
    
    // The constructor initializes the property values.
    //
    public Example() 
    {
        nValue = 2;

        hashValue = new byte[20];
        hashValue[0] = 2;
    }

    // The finalizer sets the N property to zero, and clears all 
    // the elements of the array for the Hash property. The finalizer
    // runs on a separate thread provided by the system. In some
    // cases, the finalizer can run while a member of the Example
    // instance is still executing.
    //
    ~Example() 
    {
        nValue = 0;
        if (hashValue != null)
        {
            Array.Clear(hashValue, 0, hashValue.Length);
        }
    }
}

public class Test 
{
    private static int totalCount
 = 0;
    private static int finalizerFirstCount
 = 0;

    // This variable controls the thread that runs the demo.
    private static bool
 running = true;

    // The default is to run without KeepAlive.
    private static TestKind kind = TestKind.NoKeepAlive;

    // See the comment at the end of the SafeDoWork method.
    //private static bool keepAlive = false;

    // In order to demonstrate the finalizer running first, the
    // DoWork method must create an Example object and invoke its
    // Hash property. If there are no other calls to members of
    // the Example object in DoWork, garbage collection reclaims
    // the Example object aggressively. Sometimes this means that
    // the finalizer runs before the call to the Hash property
    // completes. 
    private static void
 DoWork() 
    {
        totalCount++;

        // Create an Example object and save the value of the 
        // Hash property. There are no more calls to members of 
        // the object in the DoWork method, so it is available
        // for aggressive garbage collection.
        //
        Example ex = new Example();
        byte[] res = ex.Hash;

        // If the finalizer runs before the call to the Hash 
        // property completes, the hashValue array might be
        // cleared before the property value is read. The 
        // following test detects that.
        //
        if (res[0] != 2) 
        {
            finalizerFirstCount++;
            Console.WriteLine("The finalizer ran first at {0} iterations."
,
                totalCount);
        }
    }

    // In the SafeDoWork method the finalizer never runs first,
    // because of the KeepAlive at the end of the method.
    //    
    private static void
 SafeDoWork() 
    {
        totalCount++;

        // Create an Example object and save the value of the 
        // Hash property.
        Example ex = new Example();
        byte[] res = ex.Hash;

        // The finalizer cannot run before the property is read,
        // because the KeepAlive method prevents the Example object
        // from being reclaimed by garbage collection.
        //
        if (res[0] != 2) 
        {
            finalizerFirstCount++;
            Console.WriteLine("The finalizer ran first at {0} iterations."
,
                totalCount);
        }
        
        GC.KeepAlive(ex);
        // The KeepAlive method need never be executed. For example
,
        // if the keepAlive field is uncommented, the following line
        // of code prevents the finalizer from running first, even
        // though it is impossible for the KeepAlive method ever to
        // be executed.
        //    if (keepAlive) GC.KeepAlive(ex);
        // However, if the compiler detects that the KeepAlive can
        // never be executed, as in the following line, then it will
        // not prevent the finalizer from running first.
        //    if (false) GC.KeepAlive(ex);
    }

    // In the TrivialDoWork method the finalizer almost never runs
    // first, even without a KeepAlive at the end of the method,
    // because accessing the N property is so fast.
    //    
    private static void
 TrivialDoWork() 
    {
        totalCount++;

        // Create an Example object and save the value of the 
        // N property.
        Example ex = new Example();
        int res = ex.N;

        // The finalizer almost never runs before the property is read
,
        // because accessing the N property is so fast.
        //
        if (res != 2) 
        {
            finalizerFirstCount++;
            Console.WriteLine("The finalizer ran first at {0} iterations."
,
                totalCount);
        }        
    }

    public static void Main
 (string[] args) 
    {
        if (args.Length != 0)
        {
            string arg = args[0].ToLower();
            if (arg.Length < 10 && arg == "keepalive".Substring(0,
 arg.Length)) 
                kind = TestKind.KeepAlive;
            if (arg.Length < 8 && arg == "trivial".Substring(0,
 arg.Length)) 
                kind = TestKind.Trivial;
        }
        Console.WriteLine("Test: {0}", kind);

        // Create a thread to run the test.
        Thread t = new Thread(new ThreadStart(ThreadProc));
        t.Start();

        // The thread runs until Enter is pressed.
        Console.WriteLine("Press Enter to stop the program.");
        Console.ReadLine();
        running = false;

        // Wait for the thread to end.
        t.Join();

        Console.WriteLine("{0} iterations total; the finalizer ran first {1}
 times.",
            totalCount, finalizerFirstCount);
    }

    private static void
 ThreadProc()
    {
        switch (kind)
        {
            case TestKind.KeepAlive:
                while (running) SafeDoWork();
                break;

            case TestKind.Trivial:
                while (running) TrivialDoWork();
                break;

            default: 
                while (running) DoWork();
                break;
        }
    }

    private enum TestKind
    {
        NoKeepAlive,
        KeepAlive,
        Trivial
    }
}
/* When run with the default NoKeepAlive test, on a dual-processor
   computer, this example produces output similar to the following:

Test: NoKeepAlive
Press Enter to stop the program.
The finalizer ran first at 21098618 iterations.
The finalizer ran first at 33944444 iterations.
The finalizer ran first at 35160207 iterations.

53169451 iterations total; the finalizer ran first 3 times.
*/
using namespace System;
using namespace System::Threading;

public ref class Example
{
    // The N property is very fast, because all it does is return
    // a stored integer. Therefore the finalizer almost never runs
    // before this property is read.
    //
private:
    int nValue;
public:
    property int N
    {
        int get()
        {
            return nValue;
        }
    }

    // The Hash property is slower because it clones an array. When
    // KeepAlive is not used, the finalizer sometimes runs before
    // the Hash property value is read.
    //
private:
    array<Byte>^ hashValue;
public:
    property array<Byte>^ Hash
    {
        array<Byte>^ get()
        {
            return (array<Byte>^) hashValue->Clone();
        }
    }

    // The constructor initializes the property values.
    //
public:
    Example()
    {
        nValue = 2;

        hashValue = gcnew array<Byte>(20);
        hashValue[0] = 2;
    }

    // The finalizer sets the N property to zero, and clears all
    // the elements of the array for the Hash property. The finalizer
    // runs on a separate thread provided by the system. In some
    // cases, the finalizer can run while a member of the Example
    // instance is still executing.
    //
    ~Example()
    {
        nValue = 0;
        if (hashValue != nullptr)
        {
            Array::Clear(hashValue, 0, hashValue->Length);
        }
    }
};

public ref class Test
{
private:
    enum class TestKind
    {
        NoKeepAlive,
        KeepAlive,
        Trivial
    };

private:
    static int totalCount;
private:
    static int finalizerFirstCount;

    // This variable controls the thread that runs the demo.
private:
    static bool running = true;

    // The default is to run without KeepAlive.
private:
    static TestKind kind = TestKind::NoKeepAlive;

    // See the comment at the end of the SafeDoWork method.
    //private static bool keepAlive = false;

    // In order to demonstrate the finalizer running first, the
    // DoWork method must create an Example object and invoke its
    // Hash property. If there are no other calls to members of
    // the Example object in DoWork, garbage collection reclaims
    // the Example object aggressively. Sometimes this means that
    // the finalizer runs before the call to the Hash property
    // completes.
private:
    static void DoWork()
    {
        totalCount++;

        // Create an Example object and save the value of the
        // Hash property. There are no more calls to members of
        // the object in the DoWork method, so it is available
        // for aggressive garbage collection.
        //
        Example^ exampleObject = gcnew Example();
        array<Byte>^ hashArray = exampleObject->Hash;

        // If the finalizer runs before the call to the Hash
        // property completes, the hashValue array might be
        // cleared before the property value is read. The
        // following test detects that.
        //
        if (hashArray[0] != 2)
        {
            finalizerFirstCount++;
            Console::WriteLine("The finalizer ran first at {0}"+
                "iterations.",totalCount);
        }
    }

    // In the SafeDoWork method the finalizer never runs first,
    // because of the KeepAlive at the end of the method.
    //
private:
    static void SafeDoWork()
    {
        totalCount++;

        // Create an Example object and save the value of the
        // Hash property.
        Example^ exampleObject = gcnew Example();
        array<Byte>^ hashArray = exampleObject->Hash;

        // The finalizer cannot run before the property is read,
        // because the KeepAlive method prevents the Example object
        // from being reclaimed by garbage collection.
        //
        if (hashArray[0] != 2)
        {
            finalizerFirstCount++;
            Console::WriteLine("The finalizer ran first at {0}"+
                "iterations.",totalCount);
        }

        GC::KeepAlive(exampleObject);
        // The KeepAlive method need never be executed. For example
,
        // if the keepAlive field is uncommented, the following line
        // of code prevents the finalizer from running first, even
        // though it is impossible for the KeepAlive method ever to
        // be executed.
        //    if (keepAlive) GC.KeepAlive(ex);
        // However, if the compiler detects that the KeepAlive can
        // never be executed, as in the following line, then it will
        // not prevent the finalizer from running first.
        //    if (false) GC.KeepAlive(ex);
    }

    // In the TrivialDoWork method the finalizer almost never runs
    // first, even without a KeepAlive at the end of the method,
    // because accessing the N property is so fast.
    //
private:
    static void TrivialDoWork()
    {
        totalCount++;

        // Create an Example object and save the value of the
        // N property.
        Example^ exampleObject = gcnew Example();
        int hashArray = exampleObject->N;

        // The finalizer almost never runs before the property is
        // read because accessing the N property is so fast.
        //
        if (hashArray != 2)
        {
            finalizerFirstCount++;
            Console::WriteLine("The finalizer ran first at {0}"+
                "iterations.",totalCount);
        }
    }

public:
    static void Work(array<String^>^
 args)
    {
            if (args->Length != 0)
        {
            String^ arg = args[0]->ToLower();

            if (arg == "keepalive")
            {
                kind = TestKind::KeepAlive;
            }
            if (arg == "trivial")
            {
                kind = TestKind::Trivial;
            }
        }

        Console::WriteLine("Test: {0}", kind);

        // Create a thread to run the test.
        Thread^ sampleThread = gcnew Thread(
            gcnew ThreadStart(ThreadProc));
        sampleThread->Start();

        // The thread runs until Enter is pressed.
        Console::WriteLine("Press Enter to stop the program.");
        Console::ReadLine();
        running = false;

        // Wait for the thread to end.
        sampleThread->Join();

        Console::WriteLine("{0} iterations total; the finalizer ran " +
            "first {1} times.",totalCount, finalizerFirstCount);
    }

private:
    static void ThreadProc()
    {
        switch (kind)
        {
        case TestKind::KeepAlive:
            while(running)
            {
                SafeDoWork();
            }
            break;

        case TestKind::Trivial:
            while(running)
            {
                TrivialDoWork();
            }
            break;

        default:
            while(running)
            {
                DoWork();
            }
            break;
        }
    }
};

int main(array<String^>^ args)
{
    Test::Work(args);
};

/* When run with the default NoKeepAlive test, on a dual-processor
computer, this example produces output similar to the following:

Test: NoKeepAlive
Press Enter to stop the program.
The finalizer ran first at 21098618 iterations.
The finalizer ran first at 33944444 iterations.
The finalizer ran first at 35160207 iterations.

53169451 iterations total; the finalizer ran first 3 times.
*/

例 2

オブジェクトMain メソッド冒頭オブジェクト作成し最後に KeepAlive メソッド呼び出すまでそのオブジェクト参照しないコード例次に示しますCollect メソッドおよび WaitForPendingFinalizers メソッド呼び出しても、このオブジェクトは、30 秒持続する Main メソッド実行中は存在します

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

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();
    }
}
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 ref class MyWin32
{
public:

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

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

   // Declare the SetConsoleCtrlHandler function as external and receiving
 a delegate.

   [DllImport("Kernel32")]
   static Boolean SetConsoleCtrlHandler( HandlerRoutine^ Handler,
 Boolean Add );
};

public ref class MyApp
{
private:

   // 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 Test()
   {
      
      // Use interop to set a console control handler.
      MyWin32::HandlerRoutine^ hr = gcnew 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 );
   }

};

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

import System.* ;
import System.Threading.* ;
import 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.   

    /** @attribute DllImport("Kernel32")
     */
    public static native boolean SetConsoleCtrlHandler(HandlerRoutine
 Handler, 
        boolean Add);
    
    /** @delegate 
     */
    // A delegate type to be used as the handler routine 
    // for SetConsoleCtrlHandler.
    public delegate boolean HandlerRoutine(int
 CtrlType);

    // The control messages sent to the handler routine.
    public static int CtrlTypes[]
 = new int[] { 0,/*CTRL_C_EVENT*/
                                                1,/*CTRL_BREAK_EVENT*/
                                                2,/*CTRL_CLOSE_EVENT*/
                                                5,/*CTRL_LOGOFF_EVENT*/
                                                6 /*CTRL_SHUTDOWN_EVENT*/ };
} //MyWin32

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

        if ( MyWin32.CtrlTypes[0] == CtrlType) { 
            message = "A CTRL_C_EVENT was raised by the user.";
        }
        
        if (MyWin32.CtrlTypes[1] == CtrlType) { 
            message = "A CTRL_BREAK_EVENT was raised by the user.";
        }
        
        if (MyWin32.CtrlTypes[2] == CtrlType) { 
            message = "A CTRL_CLOSE_EVENT was raised by the user.";
        }
        
        if ( MyWin32.CtrlTypes[3] == CtrlType) { 
            message = "A CTRL_LOGOFF_EVENT was raised by the user.";
        }
        
        if (MyWin32.CtrlTypes[4] == CtrlType) {
            message = "A CTRL_SHUTDOWN_EVENT was raised by the user.";
        }
        
        // Use interop to display a message for the type of event.
        Console.WriteLine(message);
        
        return true ;
    } //Handler
   
    public static void main(String[]
 args)
    {
        // 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();
        try {
            Thread.sleep(30000);
        }
        catch (InterruptedException e) {
        }

        // 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();
    } //main
} //MyApp
プラットフォームプラットフォーム
バージョン情報バージョン情報
参照参照


このページでは「.NET Framework クラス ライブラリ リファレンス」からGC.KeepAlive メソッドを検索した結果を表示しています。
Weblioに収録されているすべての辞書からGC.KeepAlive メソッドを検索する場合は、下記のリンクをクリックしてください。
 全ての辞書からGC.KeepAlive メソッドを検索

英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「GC.KeepAlive メソッド」の関連用語

GC.KeepAlive メソッドのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



GC.KeepAlive メソッドのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
日本マイクロソフト株式会社日本マイクロソフト株式会社
© 2024 Microsoft.All rights reserved.

©2024 GRAS Group, Inc.RSS