GC.KeepAlive(Object) 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
지정된 개체를 참조하여 현재 루틴이 시작된 지점에서 이 메서드가 호출된 지점까지 가비지 컬렉션이 불가능하도록 합니다.
public:
static void KeepAlive(System::Object ^ obj);
public static void KeepAlive (object obj);
public static void KeepAlive (object? obj);
static member KeepAlive : obj -> unit
Public Shared Sub KeepAlive (obj As Object)
매개 변수
- obj
- Object
참조할 개체입니다.
예제
다음 코드 예제에서는 메서드의 시작 부분에 개체를 Main
만들고 메서드가 호출될 때까지 KeepAlive 개체를 다시 참조하지 않습니다. 개체는 메서드 및 메서드 호출에도 불구하고 Collect WaitForPendingFinalizers 메서드의 Main
30초 동안 유지됩니다.
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();
}
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();
}
}
open System
open System.Threading
open System.Runtime.InteropServices
// A simple module that exposes two static Win32 functions.
// One is a delegate type and the other is an enumerated type.
module MyWin32 =
// An enumerated type for the control messages
// sent to the handler routine.
type CtrlTypes =
| CTRL_C_EVENT = 0
| CTRL_BREAK_EVENT = 1
| CTRL_CLOSE_EVENT = 2
| CTRL_LOGOFF_EVENT = 5
| CTRL_SHUTDOWN_EVENT = 6
// A delegate type to be used as the handler routine for SetConsoleCtrlHandler.
type HandlerRoutine = delegate of CtrlTypes -> bool
// Declare the SetConsoleCtrlHandler function
// as external and receiving a delegate.
[<DllImport "Kernel32">]
extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add)
// A private static handler function in the MyApp class.
let handler (ctrlType: MyWin32.CtrlTypes) =
let message =
// Pattern match to handle the event type.
match ctrlType with
| MyWin32.CtrlTypes.CTRL_C_EVENT ->
"A CTRL_C_EVENT was raised by the user."
| MyWin32.CtrlTypes.CTRL_BREAK_EVENT ->
"A CTRL_BREAK_EVENT was raised by the user."
| MyWin32.CtrlTypes.CTRL_CLOSE_EVENT ->
"A CTRL_CLOSE_EVENT was raised by the user."
| MyWin32.CtrlTypes.CTRL_LOGOFF_EVENT ->
"A CTRL_LOGOFF_EVENT was raised by the user."
| MyWin32.CtrlTypes.CTRL_SHUTDOWN_EVENT ->
"A CTRL_SHUTDOWN_EVENT was raised by the user."
| _ -> "This message should never be seen!"
// Use interop to display a message for the type of event.
printfn $"{message}"
true
// Use interop to set a console control handler.
let hr = MyWin32.HandlerRoutine handler
MyWin32.SetConsoleCtrlHandler(hr, true) |> ignore
// Give the user some time to raise a few events.
printfn "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.
printfn "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() |> ignore
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
설명
이 메서드의 KeepAlive 목적은 가비지 수집기에서 조기에 회수될 위험이 있는 개체에 대한 참조가 있는지 확인하는 것입니다. 이 문제가 발생할 수 있는 일반적인 시나리오는 관리 코드 또는 데이터에 개체에 대한 참조가 없지만 개체가 여전히 관리되지 않는 코드(예: Windows API, 관리되지 않는 DLL 또는 COM을 사용하는 메서드)에서 사용 중인 경우입니다.
이 메서드는 매개 변수를 obj
참조하여 해당 개체가 이 메서드가 호출되는 실행 순서대로 루틴의 시작부터 지점까지 가비지 수집에 부적격하게 만듭니다. 사용 가능한 명령 범위의 시작이 아닌 끝에 이 메서드를 코딩합니다 obj
.
이 메서드는 KeepAlive 아무 작업도 수행하지 않으며 매개 변수로 전달된 개체의 수명을 연장하는 것 외에는 부작용이 발생하지 않습니다.