GC.KeepAlive(Object) Methode
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Verwijst naar het opgegeven object, waardoor het niet in aanmerking komt voor garbagecollection vanaf het begin van de huidige routine tot het punt waar deze methode wordt aangeroepen.
public:
static void KeepAlive(System::Object ^ obj);
public static void KeepAlive(object obj);
static member KeepAlive : obj -> unit
Public Shared Sub KeepAlive (obj As Object)
Parameters
- obj
- Object
Het object waarnaar moet worden verwezen.
Voorbeelden
In het volgende codevoorbeeld wordt een object aan het begin van Main de methode gemaakt en wordt pas na het einde naar het object verwezen wanneer de KeepAlive methode wordt aangeroepen. Het object blijft behouden voor de duur van 30 seconden van de Main methode, ondanks aanroepen naar de Collect methode en WaitForPendingFinalizers methoden.
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
Opmerkingen
Het doel van de KeepAlive methode is ervoor te zorgen dat er een verwijzing wordt gemaakt naar een object dat risico loopt voortijdig door de garbagecollection te worden vrijgemaakt. Een veelvoorkomend scenario waarbij dit kan gebeuren, is wanneer er geen verwijzingen naar het object in beheerde code of gegevens zijn, maar het object nog steeds wordt gebruikt in niet-beheerde code, zoals Windows API's, niet-beheerde DLL's of methoden die GEBRUIKMAKEN van COM.
Deze methode verwijst naar de obj parameter, waardoor dat object niet in aanmerking komt voor garbagecollection vanaf het begin van de routine naar het punt, in uitvoeringsvolgorde, waar deze methode wordt aangeroepen. Codeer deze methode aan het einde, niet het begin, van het bereik met instructies waar obj deze beschikbaar moet zijn.
De KeepAlive methode voert geen bewerking uit en produceert geen andere bijwerkingen dan het verlengen van de levensduur van het object dat als parameter is doorgegeven.