2009-10-16 6 views
5

Voici le code de MSDN. Je ne comprends pas pourquoi le travail n'est pas simplement fait dans la méthode régulière Dispose() ici. Quel est le but de la méthode Dispose (bool)? Qui appellerait Dispose (faux) ici?Fonction de Dispose appelant Disposer (IsDisposing) un motif en C#?

public void Dispose() 
{ 
    Dispose(true); 

    // Use SupressFinalize in case a subclass 
    // of this type implements a finalizer. 
    GC.SuppressFinalize(this);  
} 

protected virtual void Dispose(bool disposing) 
{ 
    // If you need thread safety, use a lock around these 
    // operations, as well as in your methods that use the resource. 
    if (!_disposed) 
    { 
     if (disposing) { 
      if (_resource != null) 
       _resource.Dispose(); 
       Console.WriteLine("Object disposed."); 
     } 

     // Indicate that the instance has been disposed. 
     _resource = null; 
     _disposed = true; 
    } 
} 

Répondre

14

Le finaliseur appellerait Dispose(false) - dans ce cas, vous ne touchez aucune des autres ressources gérées (qui peuvent déjà finalisés).

Personnellement, je ne suis pas souvent ce modèle - parce que j'ai seulement très, très rarement besoin d'un finaliseur, et il est aussi rare que j'écrive une implémentation non scellée de IDisposable. Si vous écrivez une classe scellée sans finalizer, j'irais pour une implémentation simple.

+1

Vous devriez toujours suivre ce modèle si vous encapsulant une ressource IDisposable dans un non étanche classe, cependant, de sorte que les sous-classes peuvent être traitées correctement (et de manière cohérente). –

+0

Même si aucun finaliseur n'est requis. –

+0

@Reed: La seule raison de faire cela lorsque les sous-classes sont impliquées est que * ils * peuvent avoir des finaliseurs - sinon pourquoi s'embêter avec un paramètre qui sera toujours vrai? –

0

Votre méthode Dispose (disposition) ne doit pas explicitement libérer des ressources si elle est appelée depuis le finaliseur, car ces ressources peuvent déjà être libérées par GC. Donc, Dispose (élimination) devrait vérifier si elle a été appelée manuellement ou par GC et agit de manière appropriée.

0

En ce qui concerne la réponse,

Votre méthode Dispose (élimination) ne doit pas explicitement les ressources libres si elle est appelée à partir finaliseur, étant donné que ces ressources peuvent être déjà libérés par GC.

Il manque un mot important. Cela devrait vraiment dire:

Votre Dispose (élimination) méthode ne doit pas explicitement libre finalisables (à savoir géré) des ressources si elle est appelée à partir finaliseur, étant donné que ces ressources peuvent être déjà libérés par GC. Seules les ressources natives doivent être libérées dans un Finalizer.

Je suis assez sûr que l'affiche signifiait cela, mais tout simplement pas assez explicite dans le message:)