Les finaliseurs sont nécessaires pour garantir la libération de la rareté des ressources dans le système, comme les descripteurs de fichiers, sockets, les objets du noyau, etc. Depuis le finaliseur fonctionne toujours à la fin de l'objets de la vie, c'est l'endroit désigné pour la libération de ces poignées.
L' Dispose
modèle est utilisé pour fournir déterministe de la destruction des ressources. Depuis l' .net runtime garbage collector est non-déterministe (ce qui signifie que vous ne pouvez jamais être sûr que lorsque le moteur d'exécution de collecter des objets anciens et d'appeler leur outil de finalisation), une méthode a été nécessaire pour assurer la déterministe libérer des ressources système. Par conséquent, lorsque vous implémentez l' Dispose
modèle correctement, vous fournir déterministe de la libération des ressources et dans les cas où le consommateur est négligent et ne pas détruire l'objet, l'outil de finalisation permettra de nettoyer l'objet.
Un exemple simple de pourquoi Dispose
est nécessaire peut être un moyen rapide et sale méthode log:
public void Log(string line)
{
var sw = new StreamWriter(File.Open(
"LogFile.log", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));
sw.WriteLine(line);
// Since we don't close the stream the FileStream finalizer will do that for
// us but we don't know when that will be and until then the file is locked.
}
Dans l'exemple ci-dessus, le fichier restera verrouillé jusqu'à ce que le garbage collector appelle le finaliseur sur l' StreamWriter
objet. Cela pose un problème car, dans l'intervalle, la méthode peut être appelée de nouveau à écrire un journal, mais cette fois, ce sera un échec car le fichier est toujours verrouillé.
La manière correcte est de disposer de l'objet lorsque sont effectuées à l'aide:
public void Log(string line)
{
using (var sw = new StreamWriter(File.Open(
"LogFile.log", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))) {
sw.WriteLine(line);
}
// Since we use the using block (which conveniently calls Dispose() for us)
// the file well be closed at this point.
}
BTW, techniquement finaliseurs et destructeurs signifient la même chose; je ne préfère appeler c# destructeurs 'finaliseurs", car sinon, ils ont tendance à embrouiller les gens avec le C++ destructeurs, qui à la différence de C# sont déterministes.