Sans me diriger vers MSDN, quelqu'un peut-il donner une explication concise et claire du but de chacun d'entre eux et du moment où les utiliser. (IntPtr, SafeHandle et HandleRef)IntPtr, SafeHandle et HandleRef - Expliqué
Répondre
IntPtr
est simplement une structure basée sur un nombre entier qui peut contenir un pointeur (par exemple, la taille de 32 bits sur les systèmes 32 bits, la taille de 64 bits sur les systèmes 64 bits).
SafeHandle
est une classe qui est destinée à contenir les poignées d'objet Win32 - elle a un finaliseur qui s'assure que le handle est fermé lorsque l'objet est GC'ed. SafeHandle
est une classe abstraite, car différentes poignées Win32 ont différentes manières dont elles doivent être fermées. Avant l'introduction de SafeHandle
, IntPtr
était utilisé pour contenir les handles Win32, mais s'assurer que ceux-ci étaient correctement fermés et empêchés d'être GC'ed était la responsabilité du programmeur.
HandleRef
est un moyen de s'assurer qu'un handle non géré n'est pas GC'ed lorsque vous êtes au milieu d'un appel P/Invoke. Sans quelque chose comme HandleRef
, si votre code managé ne fait rien avec le handle après l'appel P/Invoke, si le GC était exécuté pendant l'appel P/Invoke, il ne réaliserait pas que le handle était encore utilisé et pourrait le GC . J'imagine (mais je ne suis pas sûr et n'ai pas regardé) que SafeHandle
pourrait utiliser HandleRef
dans le cadre de sa gestion de la poignée encapsulée.
Correction mineure. Utilisez HandleRef lorsque vous ne voulez pas d'objet GC * * géré pendant PInvoke. par exemple classe HWnd {public IntPtr Handle; } HWnd a = new HWnd(); B.SendMessage (a.Handle, ...); <- a pourrait être GC'ed dans PInvoke B.SendMessage (nouveau HandleRef (a, a.Handle)) <- maintenant un ne peut pas être GC'ed dans PInvoke –
Un autre ajout: 'SafeHandle' inclut le compte de référence à empêcher les attaques de recyclage des poignées. –
Quelqu'un peut-il confirmer l'utilisation de safehandle handleref?Ou au moins a un mécanisme similaire? – Assimilater
HWnd a = new HWnd();
B.SendMessage(a.Handle, ...);
En supposant que c'est la seule référence à « un » dans le programme, ce qui équivaut à:
HWnd a = new HWnd();
IntPtr h = a.Handle;
// a is no longer needed and thus can be GC'ed
B.SendMessage(h, ...);
Le problème est que lorsque « a » est disposé, il fermera la poignée. Si cela se produit avant ou pendant l'appel à SendMessage, le handle ne sera pas valide. HandleRef évite que "a" ne soit collecté avant que le programme ne soit terminé avec h.
Il ressemble à SafeHandle n'intègre le comportement 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)
<...>
*/
Mais je ne suis pas sûr, il semble que le comportement keepalive ne peut être acheived en offrant une valeur fausse au constructeur qui simplement marque l'objet comme n'étant pas finalisable, vous devez donc appeler manuellement Dispose() de SafeHandle pour éviter les fuites de ressources dans ce cas, ai-je raison? Quelqu'un peut-il expliquer code source, ce qui est le
private extern void InternalDispose();
private extern void InternalFinalize();
?
- 1. chaîne d'outils pour WxWidgets expliqué
- 2. IntPtr jeté contre nouvelle
- 3. C#: Récupération et utilisation d'un IntPtr * par réflexion
- 4. Convertir IntPtr en int * en C#?
- 5. Comment convertir un IntPtr en flux?
- 6. Obtenir un IntPtr à une variable ulong en C#
- 7. Comment convertir un IntPtr de nouveau dans un objet
- 8. Quel est l'équivalent de IntPtr (C#) en Java?
- 9. Comment "remplir" un paramètre IntPtr avec une valeur flottante?
- 10. En C#, j'ai un IntPtr à WIN32 WndProc. Quelle est la syntaxe pour l'appeler?
- 11. Modifier une couleur d'arrière-plan de fenêtre, donné un handle IntPtr
- 12. Coffre-fort en C#
- 13. Est-ce que IntPtr.Zero est équivalent à null?
- 14. .NET 1.1 WSDL - Impossible d'utiliser IntPtr (WindowsIdentity.Token) en tant que paramètre d'entrée sur WebMethod (Service Web ASMX)
- 15. C# - Collections et coulée
- 16. Prendre une capture d'écran avec infobulle et curseur visible
- 17. numériser et enregistrer au format PDF dans C#
- 18. aspnet_compiler et msbuild.exe
- 19. Azure et Microsoft ASP.NET MVC
- 20. trouver Hauteur et largeur
- 21. Fenêtre parent et affinité de threads
- 22. Qu'est-ce que IViewObject et comment est-il utilisé dans C#
- 23. C# inter-marshaler et disposer
- 24. Interop entre C++ et C#
- 25. Pourquoi ne pas étendre JFrame et d'autres composants?
- 26. PHPLiveX et chargement html dans DIV
- 27. MultiSearch avec JqGrid et ASP.NET MVC
- 28. API Google Maps et IE6
- 29. Incident de mode d'ouverture de fichier entre C# et C++
- 30. Représentation d'image adaptée aux formats WPF et Windows
Quel est le problème avec MSDN? –
Rien. Je cherche juste un bref résumé de chacun pour m'assurer que je les utilise correctement. Si je lis MSDN et les descriptions des autres, je comprends mieux si ce que je fais est correct. – user62572