2010-11-16 7 views
3

Voir l'exemple de code de MSDN: (http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=VS.100).aspx)Finaliseurs avec Dispose() en C#

// Design pattern for a base class. 
public class Base: IDisposable 
{ 
    private bool disposed = false; 

    //Implement IDisposable. 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!disposed) 
     { 
      if (disposing) 
      { 
       // Free other state (managed objects). 
      } 
      // Free your own state (unmanaged objects). 
      // Set large fields to null. 
      disposed = true; 
     } 
    } 

    // Use C# destructor syntax for finalization code. 
    ~Base() 
    { 
     // Simply call Dispose(false). 
     Dispose (false); 
    } 
} 

Dans le GC.SupressFinalize() la mise en œuvre appelle Dispose() ;, mais fournissent un destructor pour finaliser l'objet .

À quoi sert de fournir une implémentation pour le destructeur lorsque GC.SuppressFinalize() est appelé?

Juste un peu confus quelles sont les intentions?

Répondre

5

Il y a 2 scénarios:

  • Votre code appelle Dispose (préféré) et le Finalizer est annulée, ce qui élimine les frais généraux.
  • Votre code 'fuit' l'objet et le CPG appelle le Finalizer.
+0

Merci pour ça. Faire sens lorsque l'objet est utilisé sans "utiliser" le contexte ailleurs dans le système. – msuhash

6

Si quelqu'un oublie d'appeler Dispose, le finaliseur exécutera (éventuellement) pour effectuer le nettoyage final. Puisque la finalisation nuit à la performance, idéalement personne n'oubliera Dispose. La construction utilisant aide un peu avec ça.

+0

sa finalisation qui nuit aux performances. C'est le GC qui est coûteux. Surtout sur les collections gen2/LOH et c'est là que la plupart des ressources disponibles devraient/devraient reposer. Nettoyer via la finalisation ne coûte pas plus que nettoyer via Dispose(). Mais cela arrive plus tard et de façon indéterminée. C'est la raison pour laquelle Dispose doit être appelé manuellement. – user492238

+0

@ user492238 - Quand le GC arrive, et que toutes les références à vous sont parties, avoir un finaliseur vous met dans la liste «oh je dois exécuter les finalizers sur cette liste» au lieu d'être nettoyé. Et ça fait mal perf. Vous avez raison de dire que la finalisation n'est pas le but. Il y a un finaliseur qui n'a pas encore été lancé, parce que quelqu'un a oublié d'en disposer. –

Questions connexes