Que signifient les termes ressource gérée et ressource non gérée dans .NET? Comment entrent-ils en scène?
Le terme "ressource non gérée" est généralement utilisé pour décrire quelque chose pas directement sous le contrôle du garbage collector. Par exemple, si vous ouvrez une connexion à un serveur de base de données, cela utilisera des ressources sur le serveur (pour maintenir la connexion) et éventuellement d'autres ressources non.net sur la machine cliente, si le fournisseur n'est pas entièrement écrit en code managé.
C'est pourquoi, pour quelque chose comme une connexion à une base de données, il est recommandé d'écrire ainsi votre code:
using (var connection = new SqlConnection("connection_string_here"))
{
// Code to use connection here
}
Comme cela garantit que .Dispose()
est appelé sur l'objet de connexion, garantissant que toutes les ressources non gérées sont nettoyées.
Les ressources gérées sont celles qui sont du code .NET pur et gérées par le runtime et sont sous son contrôle direct.
Les ressources non gérées sont celles qui ne le sont pas. Poignées de fichiers, mémoire épinglée, objets COM, connexions à la base de données, etc.
Dans le Q&A Que sont les ressources non gérées?1, Bruce Wood a publié ce qui suit:
Je pense aux termes "géré" et "non géré" de cette façon:
"Géré" fait référence à tout ce qui se trouve dans le sandbox .NET. Cela inclut toutes les classes .NET Framework.
"Non géré" fait référence à la nature sauvage en dehors du bac à sable .NET. Cela inclut tout ce qui vous est renvoyé via des appels aux fonctions de l'API Win32.
Si vous jamais appelez une fonction API Win32 et jamais récupérez tous les objets "handle" Win32, alors vous ne détenez aucune ressource non gérée. Les fichiers et les flux que vous ouvrez via les méthodes de classe .NET Framework sont tous des wrappers gérés.
Commentaire: Vous ne détenez peut-être pas une ressource non gérée directement. Cependant, vous pouvez détenir une ressource non managée indirectement via une "classe wrapper" gérée telle que System.IO.FileStream . Une telle classe wrapper implémente généralement IDisposable (soit directement soit via l'héritage).
... de nombreux objets gérés (.NET Framework) contiennent des ressources non managées à l'intérieur, et vous souhaitez probablement en supprimer () dès que vous le pouvez, ou au moins offrir à vos appelants la possibilité de le faire. C'est là qu'intervient l'écriture de votre propre méthode Dispose (). Essentiellement, l'implémentation de IDisposable () fait deux choses pour vous:
Vous permet de vous débarrasser de toutes les ressources que vous avez récupérées directement du système d'exploitation derrière le dos de .NET (ressources non gérées).
Vous et vos appelants vous permettent de libérer de lourds objets .NET/objets .NET qui détiennent de précieuses ressources dans leurs petites mains sales que vous/vos appelants souhaitez libérer maintenant.
Commentaire: En implémentant IDisposable
et en fournissant ainsi une méthode Dispose()
, vous permettez à un utilisateur de votre classe de libérez de façon déterministe façonnez toutes les ressources non managées détenues par une instance de votre classe.
1 Lien initialement partagé dans réponse de Sachin Shanbhag . Documents cités datés du 2005-11-17. Notez que j'ai légèrement modifié le contenu cité.
La différence fondamentale entre une ressource gérée et non gérée est que le garbage collector connaît toutes les ressources gérées, à un moment donné le GC viendra et nettoiera toute la mémoire et les ressources associées à un objet géré. Le GC ne connaît pas les ressources non gérées, telles que les fichiers, le flux et les poignées, donc si vous ne les nettoyez pas explicitement dans votre code, vous vous retrouverez avec des fuites de mémoire et des ressources verrouillées.
Pour plus de détails - http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources
Les ressources gérées sont des ressources qui peuvent être libérées par le garbage collector et les ressources non managées ne peuvent pas être libérées par le garbage collector à cet effet, un destructeur est requis.