Sin señalarme a MSDN, podría alguien dar una explicación clara y concisa del propósito de cada uno de estos y cuándo usarlos. (IntPtr, SafeHandle y HandleRef)IntPtr, SafeHandle y HandleRef - Explicación
Respuesta
IntPtr
es simplemente una estructura simple basada en enteros que puede contener un puntero (es decir, tamaño de 32 bits en sistemas de 32 bits, tamaño de 64 bits en sistemas de 64 bits).
SafeHandle
es una clase que está destinada a contener identificadores de objetos Win32; tiene un finalizador que asegura que el identificador se cierre cuando el objeto recibe GC. SafeHandle
es una clase abstracta porque los diferentes identificadores de Win32 tienen diferentes formas en que deben cerrarse. Antes de la introducción de SafeHandle
, IntPtr
se usaba para mantener los identificadores de Win32, pero asegurarse de que se cerraran correctamente y se evitara que pasaran por GC era responsabilidad del programador.
HandleRef
es una forma de asegurarse de que un identificador no administrado no recibe GC cuando está en medio de una llamada P/Invoke. Sin algo como HandleRef
, si su código administrado no hace nada con el controlador después de la llamada P/Invoke, si el GC se ejecutó durante la llamada P/Invoke no se daría cuenta de que el identificador aún estaba en uso y podría GC . Me imagino (pero no estoy seguro y no lo he buscado) que SafeHandle
podría usar HandleRef
como parte de su gestión del identificador encapsulado.
Corrección secundaria. Use HandleRef cuando no desee un objeto * managed * GC'ed durante PInvoke. por ejemplo clase HWnd {public IntPtr Handle; } HWnd a = new HWnd(); B.SendMessage (a.Handle, ...); <- a podría recibir GC en PInvoke B.SendMessage (new HandleRef (a, a.Handle)) <- ahora no se puede aplicar GC en PInvoke –
Otra adición: 'SafeHandle' incluye recuento de referencias para prevenir manejar ataques de reciclaje. –
¿Alguien puede confirmar que safehandle usa handleref?¿O al menos tiene un mecanismo similar? – Assimilater
HWnd a = new HWnd();
B.SendMessage(a.Handle, ...);
Suponiendo que esta es la única referencia a "a" en el programa, esto es equivalente a:
HWnd a = new HWnd();
IntPtr h = a.Handle;
// a is no longer needed and thus can be GC'ed
B.SendMessage(h, ...);
El problema es que cuando "a" está dispuesto, se va a cerrar el mango. Si esto ocurre antes o durante la llamada a SendMessage, el identificador no será válido.
HandleRef evita que se recolecte "a" basura antes de que el programa se termine con h.
Parece que SafeHandle no incorporar el comportamiento KeepAlive de HandleRef: Project Roslyn SafeHandle.cs http://referencesource.microsoft.com/#mscorlib/system/runtime/interopservices/safehandle.cs,743afbddafaea263
/*
Problems addressed by the SafeHandle class:
1) Critical finalization - ensure we never leak OS resources in SQL. Done
without running truly arbitrary & unbounded amounts of managed code.
2) Reduced graph promotion - during finalization, keep object graph small
3) GC.KeepAlive behavior - P/Invoke vs. finalizer thread ---- (HandleRef)
<...>
*/
Pero no estoy seguro, parece que el comportamiento de mantenimiento de conexión solamente se puede lograr proporcionando valor falso al constructor, que simplemente marca el objeto como no finalizable, por lo que debe llamar a SafeHandle's Dispose() manualmente para evitar la fuga de recursos en ese caso, ¿estoy en lo cierto? Puede alguien explicar el código fuente, lo que es el
private extern void InternalDispose();
private extern void InternalFinalize();
?
- 1. ¿Puedo usar SafeHandle en lugar de IntPtr?
- 2. Safehandle en C#
- 3. ¿Qué son las asas? IntPtr
- 4. C# use IDisposable o SafeHandle?
- 5. ¿Cuál es la diferencia entre HandleRef y GCHandle?
- 6. IntPtr de matriz de bytes y Back
- 7. snprintf y sprintf explicación
- 8. Eteración: explicación y ejemplo
- 9. IntPtr vs ref C#
- 10. C# punteros vs IntPtr
- 11. ¿Qué es intptr?
- 12. IntPtr vs UIntPtr
- 13. Explicación y uso de JSONP
- 14. Explicación de OpenMP y MPI
- 15. C# Convertir IntPtr en int
- 16. nueva IntPtr (0) vs. IntPtr.Zero
- 17. Cómo liberar IntPtr en C#?
- 18. Cómo convertir IntPtr en byte *
- 19. No se puede agregar un IntPtr y un Int
- 20. Explicación de ++ val ++ y ++ * p ++ en C
- 21. int vs IntPtr cuando tiene un controlador?
- 22. ¿Por qué usar IntPtr para manejarlo?
- 23. Explicación de los números de mensaje de SendMessage?
- 24. Explicación de contribute_to_class
- 25. ¿Cómo se puede usar un SafeHandle en una firma de P/Invoke que requiere un puntero nulo en ciertos casos?
- 26. Algoritmo Quickselect - Explicación simplificada
- 27. Algoritmo FASTA Explicación
- 28. Explicación de Func
- 29. Android runOnUiThread explicación
- 30. onMeasure vista personalizada explicación
¿Qué pasa con MSDN? –
Nada. Solo estoy buscando un breve resumen de cada uno para asegurarme de que los estoy usando correctamente. Si leo las descripciones de MSDN y de otras personas, tengo una mejor idea de si lo que estoy haciendo es correcto. – user62572