En .NET, dans quelles circonstances devrais-je utiliser GC.SuppressFinalize()
?
Quel avantage(s) me donne l'utilisation de cette méthode?
En .NET, dans quelles circonstances devrais-je utiliser GC.SuppressFinalize()
?
Quel avantage(s) me donne l'utilisation de cette méthode?
SuppressFinalize
ne doit être appelé que par une classe qui a un finaliseur. Cela informe le Garbage Collector (GC) que this
objet a été entièrement nettoyé.
Le modèle IDisposable
recommandé lorsque vous avez un finaliseur est :
public class MyClass : IDisposable
{
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// appelé via myClass.Dispose().
// OK d'utiliser toutes les références d'objets privés
}
// Libérer les ressources non managées.
// Définir les champs importants à null.
disposed = true;
}
}
public void Dispose() // Implémentez IDisposable
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass() // le finaliseur
{
Dispose(false);
}
}
Normalement, le CLR garde un œil sur les objets avec un finaliseur lorsqu'ils sont créés (ce qui les rend plus coûteux à créer). SuppressFinalize
indique au GC que l'objet a été nettoyé correctement et n'a pas besoin d'aller dans la file d'attente du finaliseur. Cela ressemble à un destructeur C++, mais n'agit rien du tout de la même façon.
L'optimisation SuppressFinalize
n'est pas anodine, car vos objets peuvent vivre longtemps en attendant dans la file d'attente du finaliseur. Ne soyez pas tenté d'appeler SuppressFinalize
sur d'autres objets, il s'agit d'un défaut grave en attente de se produire.
Les directives de conception nous indiquent qu'un finaliseur n'est pas nécessaire si votre objet implémente IDisposable
, mais si vous avez un finaliseur, vous devez implémenter IDisposable
pour permettre un nettoyage déterministe de votre classe.
La plupart du temps, vous devriez pouvoir vous en sortir avec IDisposable
pour nettoyer les ressources. Vous ne devriez avoir besoin d'un finaliseur que lorsque votre objet détient des ressources non managées et que vous devez garantir que ces ressources sont nettoyées.
Remarque : Parfois les codeurs ajouteront un finaliseur aux versions de débogage de leurs propres classes IDisposable
afin de tester que le code a correctement disposé de leur objet IDisposable
.
public void Dispose() // Implémentez IDisposable
{
Dispose(true);
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~MyClass() // le finaliseur
{
Dispose(false);
}
#endif
SupressFinalize
indique au système que tout le travail qui aurait été effectué dans le finaliseur a déjà été effectué, de sorte que le finaliseur n'a pas besoin d'être appelé. À partir de la documentation .NET :
Les objets qui implémentent l'interface IDisposable peuvent appeler cette méthode depuis la méthode IDisposable.Dispose pour empêcher le garbage collector d'appeler Object.Finalize sur un objet qui n'en a pas besoin.
En général, la plupart des méthodes Dispose()
devraient pouvoir appeler GC.SupressFinalize()
, car elles devraient nettoyer tout ce qui serait nettoyé dans le finaliseur.
SupressFinalize
est simplement quelque chose qui fournit une optimisation qui permet au système de ne pas se donner la peine de mettre l'objet dans la file d'attente du thread du finaliseur. Un Dispose()
/finaliseur correctement écrit devrait fonctionner correctement avec ou sans un appel à GC.SupressFinalize()
.
Généralement, lors de la mise en oeuvre du modèle IDisposable lorsque vous n'avez pas besoin de finaliser votre objet. Consultez http://www.blackwasp.co.uk/IDisposable.aspx pour des exemples.
Dispose(true);
GC.SuppressFinalize(this);
Si l'objet a un finaliseur, .net place une référence dans la file d'attente de finalisation.
Puisque nous avons appelé Dispose(true)
, cela efface l'objet, donc nous n'avons pas besoin que la file d'attente de finalisation fasse ce travail.
Donc, l'appel de GC.SuppressFinalize(this)
supprime la référence dans la file d'attente de finalisation.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.