La meilleure façon de disposer d'une liste
Je vais avoir des objets de la Liste. Comment puis-je éliminer de la liste?
Par exemple,
List<User> usersCollection =new List<User>();
User user1 = new User();
User user2 = new User()
userCollection.Add(user1);
userCollection.Add(user2);
Si j'ai mis userCollection = null;
ce qui va arriver?
foreach(User user in userCollection)
{
user = null;
}
Laquelle est la meilleure?
- Votre code ne contient pas de disposer des opérations.
- Disposer est de libérer des ressources non managées. Si une liste n'a pas de références à celui-ci, il sera libéré par le garbabe collecteur approprié.
- et invite de nettoyage (de certains de la mise en œuvre spécifique de la nature) de certaines ressources gérées; mais oui, non géré est plus fréquente
InformationsquelleAutor Vivekh | 2011-07-06
Vous devez vous connecter pour publier un commentaire.
Meilleure idée est de laisser le garbage collector.
Votre
foreach
ne changera rien puisque seule la référence sera définie ànull
pas l'élément dans la liste. Réglage de la liste denull
pourrait en fait causer la collecte des ordures à se produire plus tard qu'elle pourrait avoir (voir ce post C#: doit variables d'objet être assignée à null?).Tout d'abord, vous ne pouvez pas "jeter" une liste car il n'est pas
IDisposable
, et vous ne pouvez pas le forcer à être collectées car ce n'est pas la façon dont C# fonctionne. Généralement vous ne rien ici. Alors, quand pourrait nous avons besoin de faire rien?Le seul moment où vous devez rien est si c'est un champ (ou capturé variable /variable d'un bloc itérateur /etc) et l'instance (/délégué/itérateur) va vivre une longue tandis que les plus - alors peut-être définir le champ de la liste de à null. Notez, cependant, que si un autre code a encore une référence à la liste alors tout sera toujours accessible.
Je ne suis pas d'accord que vous ne devriez pas faire quoi que ce soit si vous n'avez pas besoin de les objets dans la liste. Si les objets implémentent l'interface
System.IDisposable
ensuite, le concepteur de l'objet pensé que l'objet contient des ressources rares.Si vous n'avez pas besoin de l'objet et plus seulement affecter null à l'objet, ces ressources ne sont pas libérés jusqu'à ce que le garbage collector finalise l'objet. Dans le même temps, vous ne pouvez pas utiliser cette ressource pour quelque chose d'autre.
Exemple:
Envisagez-vous de créer une image à partir d'un fichier, et décidez que vous n'avez pas besoin ni l'image, ni le fichier plus. Le Code pourrait ressembler à la suivante:
La bonne méthode serait:
Les mêmes comptes pour les objets dans une liste, ou n'importe quelle collection. Tous les objets de la collection sont IDisposable doivent être éliminés. Le Code devrait ressembler à:
Ou si vous souhaitez créer un IEnumerable fonction d'extension
Toutes les listes /dictionnaires /lecture seule listes /collections /etc pouvez utiliser ces méthodes, parce qu'ils implémentent l'interface IEnumerable. Vous pouvez même l'utiliser si pas tous les éléments de la séquence de mettre en œuvre le Système.IDisposable.
Une autre idée pour ce post... Si vous étiez désireux de s'assurer que tous les membres d'une collection sont éliminés correctement, vous pouvez utiliser les éléments suivants de la méthode d'extension:
Ce regarde à travers la collection pour tout membre qui met en œuvre
IDisposable
et le mettre au rebut. À partir de l'exécution de votre code, vous pouvez nettoyer la liste comme ceci:Cela permettra d'assurer que tous les membres de la chance de libérer des ressources, et la liste est vide.
Vous n'avez pas fourni suffisamment de contexte. La portée est ici essentielle.
Je pense que le GC doit être suffisamment intelligente pour gérer la mémoire allouée pour les utilisateurs et la collection sans avoir à régler quoi que ce soit à null.
Si la collection supprime des utilisateurs qui ne sont pas nécessaires à partir de la collection, et pas les autres objets se réfèrent à eux, ils seront GC avais sans que vous ayez à fournir des indices.
Le GC ne pas nettoyer un objet tant qu'il y aura un live de référence. Éliminer toutes les références et qu'il puisse faire son travail.
Encore un autre exemple d'une extension de la méthode que vous pouvez utiliser pour disposer d'une liste d'objets qui implémentent l'interface IDisposable. Celui-ci utilise la syntaxe LINQ.
Meilleure façon est
Que GC prendra soin du reste.
null
quand il est hors de portée?Et un générique de mise en œuvre qui sera travaillé (apparaissent dans
List<T>
méthode de la liste) si l'élément mis en œuvreIDisposable
Pour être utilisé de cette façon
Il y a une bien meilleure manière lors de l'utilisation Système.Réactive.Disposeables:
Initialiser une nouvelle propriété de type
CompositeDisposable
et à ajouter les articles à usage unique à cette collection. Alors jetez juste un.Voici un exemple de code comment le faire dans un typique WPF/UWP ViewModel sans indroducing tout fuites de mémoire:
mettre en œuvre
IDisposable
comme ceci:et ici, c'est la classe d'extension pour obtenir le
.AddRange()
méthode:Voir aussi
BooleanDisposable
vous permet d'interroger si l'objet a déjà obtenu éliminésCancellationDisposable
est comme BooleanDisposable mais avec un jeton d'annulationContextDisposable
vous permet de disposer dans un contexte de threadMultipleAssignmentDisposable
remplace un jetable avec un autre sans se débarrasser de la vieille jetablesSerialDisposable
remplace le vieux disposalbe avec l'autre, tandis que l'élimination de l'ancien jetablesSingleAssignmentDisposable
magasins d'un revenu qui ne peuvent pas replaed avec un autre jetablesBeaucoup de ces réponses ont quelque chose comme...
Il n'y a pas de réponse unique mention de la raison .Clear() est utile. La réponse est le découplage des objets de la collection de la fois de la collecte des uns et des autres.
Le plus vous dissociez sur la déchirure en bas de n'importe quel objet de la plus grande est la chance que le garbage collector fera du travail en temps opportun. Souvent importante .NET des fuites de mémoire grâce à de larges graphes d'objets qui sont à 99% inutilisés qui ont un élément qui est encore référencée.
Je pense que c'est une bonne pratique...
...dans une classe de mise en œuvre IDisposable.
Je ne dis pas que la mise en œuvre de IDisposable sur tout, et de cette façon, je me dis que si il se trouve que vous avez besoin pour mettre en œuvre jetez vous pourriez aussi bien le faire. Je n'en œuvre IDisposable lorsque l'objet...
La seule fois où je voudrais seulement mettre en œuvre le Jeter juste pour dissocier un objet lorsque vous savez que vous avez une fuite de mémoire et de l'analyse d'un profileur de mémoire a suggéré qu'il pourrait être utile.
Pourquoi voulez-vous de disposer de la liste? Le GC va le faire pour vous si il n'y a pas de références à elle.
La Collecte Des Ordures: msdn.microsoft.com/en-us/library/0xy59wtx.aspx
Comme tout le monde a mentionné laisser à la GC, c'est la meilleure option et ne pas forcer le GC.
Définition de la variable à null, la marque de la variable pour la GC.
si votre après plus d'info: Les meilleures Pratiques pour Forcer la Collecte des Ordures en C#
Une autre idée est d'utiliser des crochets qui comprennent la portée de la variable que vous souhaitez garder.
par exemple.
Je suis venu à travers des scénarios où, quand de grandes quantités de données sont en cours de traitement, le GC ne nettoie pas jusqu'à après la collection a disparu hors de portée (techniquement, le GC ne sa collection lorsqu'elle le juge opportun et ce n'est pas lorsque la collection est hors de portée).
Dans ces (rares) scénarios, j'ai utilisé la classe suivante:
Vous pouvez alors l'utiliser comme une Liste normale, par exemple
Puis d'appeler la méthode dispose lorsque vous avez terminé:
Ou, à défaut, il déclare dans une instruction d'utilisation:
Cela provoque alors la GC pour faire sa collection immédiatement une fois que le DisposableList est hors de portée ou éliminés.
Je vois beaucoup de réponses à l'appel de Disposer d'un objet à l'intérieur d'une boucle foreach sur une collection.
Depuis Jetez simplement les marques de l'objet à supprimé la prochaine fois que le garbage collector est exécuté, il va travailler sur ok. En théorie cependant, l'élimination d'un élément susceptible de modifier la collecte et la rupture de la boucle foreach, de sorte qu'il serait plus robuste d'abord recueillir ces objets jetables, effacer la liste d'origine, et l'appel de la jeter dans une pour ou en boucle à partir de la fin et de retrait de l'objet à chaque itération, par exemple, l'appel de la méthode suivante:
Je suis en train de l'utiliser DeleteItemsInList pour d'autres fins, par exemple pour supprimer les fichiers: DeleteItemsInList(Fichier.Delete) )
Que ceux qui ont déclaré, dans le cas général, il ne devrait pas être nécessaire de disposer d'une telle liste.
Un cas où je dois disposer d'un élément dans une liste est de travailler avec le Ruisseau, je collectionne un peu cuit à la vapeur, de transformer les données, puis débarrassez-vous de ces flux et de ne garder que mes objets transformés pour la poursuite du traitement.
J'espère que vous avez rencontré un souvenir d'exception si vous vous posez cette question, si non, vous devez créer un test à cause d'un manque de mémoire exception.
En supposant que vous avez réellement des problèmes de mémoire, vous devez identifier ce qui, dans l'objet Utilisateur est de consommer la totalité de votre mémoire. Définissez les propriétés de l'Utilisateur de l'objet à null qui consomment le plus de mémoire.
Ensuite, vous pouvez garder votre liste d'utilisateurs et de laisser le garbage collector de nettoyage les propriétés qui consomment la totalité de votre mémoire.
Si votre article dans la liste est géré par les nations unies de l'objet, alors vous pouvez appeler dispose() de chaque objet par l'itération d'elle.
Si l'objet de liste d'objet géré, alors vous n'avez rien à faire. GC prendra soin.