9
votes

Les commandes claires ne les disposent pas - quel est le risque?

Il y a plusieurs threads ( A , b , C , etc.) sur le fait que Effacer les éléments () dans les conteneurs de composants .NET ne sont pas Disposez eux (en appelant disposer ( vrai ).

Le plus fréquemment, IMHO, les composants effacés ne sont plus utilisés dans l'application, il a donc besoin explicitement être disposé après les éclaircir des conteneurs parent.

Peut-être est peut-être une bonne idée de la méthode CLEAR de la collection présentant un paramètre Bool Dispose que lorsqu'il dispose également d'éléments de collecte avant de supprimer de la liste?


4 commentaires

S'il y a un appel à disposer dans le finaliseur, ils seront disposés. S'il n'y a pas encore, il y a probablement (si le programmeur a suivi des pratiques acceptées) rien n'a été sans gré à disposer et il est prudent de les ordures.


@Aviad: Le problème que la méthode de disposer ne sera jamais appelée par le GC, vous devez donc le faire par vous-même, avant d'appeler Clear On Collection.


Ce que je veux dire, c'est que si le programmeur du contrôle n'a pas mis en disposition un appel dans son finaliseur (qui est appelé lorsque l'objet est recruté) - il n'y a probablement rien à disposer.


Voir aussi la description détaillée de HANS des problèmes ici: Stackoverflow.com/a/2014427/366904


3 Réponses :


16
votes

Demander des modifications comme celle-ci est inutile, l'équipe Windows Forms a été dissoute il y a tout à fait. Il est en mode de maintenance, seuls les problèmes de sécurité et les incompatibilités du système d'exploitation sont pris en compte.

Il est assez simple de créer votre propre méthode pour le faire: P>

  panel1.Controls.Clear(true);


9 commentaires

IIRC, lorsque vous DISPOSER A Contrôle , il supprime automatiquement le contrôle à partir du contrôle ControlCollection , vous n'avez donc pas besoin du Removeat (et pourrait se retrouver avec un indexautofrangeException ).


Ouais ... au moins pour .NET 2 Cela ne fonctionnera pas. Mais la question est un peu autre chose. Existe-t-il un "risque" appelant "clair" sans disposer?


Bien sûr, vous allez fuir les contrôles. N'était-ce pas évident des autres threads?


@nobugs: Oui, maintenant, en d'autres termes, vous dites que, normalement, appelez Effacer sans Dispose n'a aucun sens; Microsoft ne changera pas le code, il nous faut donc tout ce que nous avons à faire est de vous rappeler que, utilisez ces méthodes ensemble pour .NET <3.5 et peut également mettre en œuvre des méthodes d'extension dans .NET> = 3.5


Euh, je n'ai pas dit ça. En fait, je ne pense pas que Clear () ait beaucoup de sens en général. WF a été optimisé pour utiliser usercontrols et le concepteur. Les commandes de conteneurs savent déjà comment éliminer correctement leurs contrôles d'enfants.


@nobugs: Je pense que Effacer C'est un membre classique de toute collection (non seulement le composant One), cela devrait être son sens. Contrôles de conteneur "Je sais déjà comment disposer correctement"? Que veux-tu dire? Comme nous pouvons le voir, ce n'est pas le cas "clair". Ils peuvent probablement au moins ajouter un attribut "obsolète" sur les conteneurs de contrôle "Clear".


L'élimination d'une commande dispose automatiquement de tout contrôle des enfants dans sa collecte de commandes. Aucune aide n'est nécessaire.


@nobugs: Oui, vous avez raison. Mais, après Effacer le parent aura tout contrôle dans sa collection de contrôles, de sorte que toutes les commandes Effacer ed resteront un Disposez D, lorsque la commande parent est disposée.


@serhio: Êtes-vous sûr que Controls.Clear () n'est pas remplacé? Je pense que cela gère le dispositif que HANS pointe.



1
votes

Répondre à la question "Quel est le risque", le risque (ou un risque) est à court de poignées de fenêtre, bien qu'elle puisse prendre un certain temps.

J'ai un "concepteur de fenêtre" qui génère une fenêtre d'un scénario. Chaque fois que je change le script, la fenêtre est reconstruite (les commandes effacé et accusés). Avec une fenêtre particulièrement complexe et utilise Controls.Clear () code> à chaque fois, après de nombreuses dizaines de rafraîchissements, je serai éventuellement obtenir une exception "plus de fenêtre" et ne pas pouvoir créer plus de contrôles . P>

assez facile pour remplacer le Controls.Clear () Code> Appelez quelque chose comme: P>

Controls.Cast<Control>().ForEach(c => c.Dispose());


0 commentaires

0
votes

@hans Réponse passante est bon mais en cas de programmation asynchrone, vous devez envisager de retirer l'objet avant de l'éliminer pour éviter que le thread soit itérale sur un objet disposé.

Plus ou moins quelque chose comme ceci: xxx


0 commentaires