10
votes

Comment mettre en œuvre correctement les éléments idious

J'ai vu tellement le code C # dans mon temps en tant que développeur qui tente d'aider le GC dans le cadre de la définition de variables à NULL ou à appeler () sur les classes (ensemble de données par exemple) dans ses propres classes éliminer () la méthode que Je me demandais s'il est nécessaire de la mettre en œuvre dans un environnement géré.

est ce code une perte de temps dans son modèle de conception? xxx


0 commentaires

4 Réponses :


2
votes

Pas entièrement. Si vous avez des variables de membre jetables, vous devriez probablement en disposer comme ça. Votre objet peut vivre plus longtemps que la portée du travail qu'il fait car le collecteur des ordures n'est pas garanti d'exécuter à une heure particulière.

Réglage des variables gérées vers NULL est une perte de temps. L'objet ne sera pas plus rapide GC'D.


0 commentaires

11
votes

Le GC n'est pas appel .Dispose () (il appelle toutefois la méthode finalisez ~ myClass () méthode que vous peut fournir un appel à la méthode () pour que les ressources gérées automatiquement lorsque le GC décide de nettoyer votre classe).

Vous devez toujours fournir un moyen de disposer de ressources internes telles que Datatesets AU CODE qui utilise vos classes (et assurez-vous que vous appelez réellement .Dispose () ou enveloppez le constructeur dans un en utilisant ). Utilisation de Idisposable sur vos classes qui utilisent des ressources internes sont fortement recommandées.

de msdn :

L'utilisation principale de cette interface est libérer des ressources non gérées. Les collecteur de déchets automatiquement libère la mémoire allouée à un objet géré lorsque cet objet n'est pas utilisé plus longtemps. Cependant, ce n'est pas possible de prédire quand des ordures la collecte se produira. Par ailleurs, Le collecteur des ordures n'a aucune connaissance des ressources non gérées telles que la fenêtre gère, ou ouvrir des fichiers et des flux. xxx


0 commentaires

6
votes

Non, disposer des méthodes ne sont pas une perte de temps.

Le modèle d'élimination est là pour permettre à un appelant de nettoyer une classe dès qu'ils l'ont fini, plutôt que d'attendre que le GC le recueille. Le retard n'a pas beaucoup d'importance pour la mémoire de tas uni, c'est pourquoi les classes de base comme string ne le mettent pas en œuvre. Ce qui élimine est utile pour le nettoyage des ressources non gérées . Quelque part en interne, la classe de jeu de données utilise une ressource non gérée. Il fournit donc une méthode d'expiration pour vous permettre de le faire savoir quand cette ressource non gérée peut être libérée.

Si le motif a été suivi correctement du jeu de données aura également un finaliseur (ou une sous-classe), ce qui signifie que si vous ne le disposez pas manuellement, le GC serait exécuté, le finaliseur serait appelé et la ressource non gérée serait nettoyé de cette façon. Cette ressource non gérée peut être importante, imaginez s'il s'agissait d'une serrure de fichier ou d'une connexion de base de données, vous ne voulez pas vraiment vous suspendre en attendant que le GC fonctionne avant de pouvoir réutiliser votre connexion de base de données. Dispose fournit une manière déterministe de nettoyer les ressources lorsqu'elles sont finies plutôt que de compter sur le GC non déterministe.

comme pour régler des variables sur NULL dans une méthode d'élimination. Presque tous les cas, ce serait inutile. définir une variable pour NULL supprime une référence à cette variable, qui le rendra éligible à la collecte des ordures (si c'est la dernière référence), mais que vous disposez de la classe de toute façon, vous risquez de sortir de la portée du contenant contenant classe afin que la classe interne devienne éligible de toute façon.

Si vous avez des variables membres à l'intérieur de votre classe qui sont jetables que vous avez créées (non seulement des références que vous détenez), vous devriez toujours appeler à les disposer de la méthode d'expulsion de votre propre classe, mais ne vous embêtez pas de les mettre en place sur NULL.


0 commentaires

0
votes

Un camion à ordures vient dans ma région chaque semaine, mais cela ne recueille pas mes ordures à moins que je ne mettais ma poubelle de manière à pouvoir collecter.

Vous devez simplement supprimer tous les abonnements d'événements non désirés, référence et transparent les gestionnaires non gérés. . Ensuite, le collectionneur des ordures prendra soin du reste. P>

Exemple indique la meilleure pratique générale pour mettre en œuvre une interface Idisposable. Référence: https: // msdn. microsoft.com/en-us/library/system.idisposable.dispose.dispose(v=vs.110).aspx P>

public class DisposeExample
{
    // A base class that implements IDisposable. 
    // By implementing IDisposable, you are announcing that 
    // instances of this type allocate scarce resources. 
    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource. 
        private IntPtr handle;
        // Other managed resource this class uses. 
        private Component component = new Component();
        // Track whether Dispose has been called. 
        private bool disposed = false;

        // The class constructor. 
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable. 
        // Do not make this method virtual. 
        // A derived class should not be able to override this method. 
        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method. 
            // Therefore, you should call GC.SupressFinalize to 
            // take this object off the finalization queue 
            // and prevent finalization code for this object 
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios. 
        // If disposing equals true, the method has been called directly 
        // or indirectly by a user's code. Managed and unmanaged resources 
        // can be disposed. 
        // If disposing equals false, the method has been called by the 
        // runtime from inside the finalizer and you should not reference 
        // other objects. Only unmanaged resources can be disposed. 
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called. 
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed 
                // and unmanaged resources. 
                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up 
                // unmanaged resources here. 
                // If disposing is false, 
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;

            }
        }

        // Use interop to call the method necessary 
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code. 
        // This destructor will run only if the Dispose method 
        // does not get called. 
        // It gives your base class the opportunity to finalize. 
        // Do not provide destructors in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here. 
            // Calling Dispose(false) is optimal in terms of 
            // readability and maintainability.
            Dispose(false);
        }
    }
    public static void Main()
    {
        // Insert code here to create 
        // and use the MyResource object.
    }
}


4 commentaires

Le but de Idisposable ne doit pas détruire les ressources - c'est à libérer eux. Lorsqu'un fichier filtream ouvre un fichier, il demande que l'OS empêche toute personne d'utiliser le fichier jusqu'à nouvel ordre; Appelant Dispose sur le filtream ne détruit pas le fichier - au contraire, il le rend utilisable par d'autres entités . Le CPG opère sur le principe qu'il ne devrait y avoir aucune ruée pour détruire des choses lorsqu'il y a de l'espace pour les détenir, mais une fois que le code n'a plus d'utilisation pour un filtream , il devrait essayer de rendre le fichier à nouveau disponible pour autre code dès que possible.


@supercat: Pas tout à fait sûr de ce que vous essayez de dire. Je suppose que le jettreameram Dispose libère le gestionnaire de fichiers et laissez le collecteur à ordures pour effacer les instances gérées. Il est seul but de ne pas le rendre utilisable pour les autres.Si vous n'ouvrez pas le fichier exclusivement, il peut être en mesure d'utiliser par d'autres personnes de toute façon.


La raison que GC n'est pas suffisante pour des choses telles que filtream n'est-ce pas Toujours détient une serrure de fichier d'une manière qui interfère avec d'autres entités qui doivent utiliser le fichier , mais qu'ils parfois font, et il est généralement plus facile de libérer des ressources lorsque elles ne devaient plus, sans tenir compte de savoir si l'affirmation existerait réellement, que d'identifier les cas où la contention n'existera pas et abandonne ressources sans les libérer dans de tels cas. Notez que parfois ne doit pas nécessairement être très "souvent" pour faire Idisposable intéressant. Même si abandonnant un flux de fichiers ...


... travaillerait 99% du temps, il peut être plus facile d'avoir un appel de code Dispose sur les flux de fichiers 100% du temps où ils ne sont plus nécessaires à ce que le code ne soit plus nécessaire. Éliminez-les de leur travail 100% du temps.