Détecter les fuites WindowHandle dans une application c #
-
19-09-2019 - |
Question
Je suis tombé sur cette exception hier:
Win32Exception: Fehler beim Erstellen des Fensterhandles
pourrait se traduire par:
Win32Exception: Error while creating the windowhandle
Je sais comment résoudre ce (même écrit un court billet de blog sur le sujet - en allemand)
Mais je ne sais pas où ma demande pourrait être « fuite » des contrôles non aliénées, qui ont encore fenêtres poignées.
Est-il possible de détecter / trouver des cas que
- mettre en œuvre
IDisposable
- Vous
Parent == null
Les objets correspondant à ces contraintes semblent être de bons candidats.
La solution
Toute profileur de mémoire décente vous montrera les instances de contrôle. Ils ne seront pas les ordures collectées, leur propriété Handle les maintient en vie. Il y aura près de 10 000 d'entre eux. Vous pouvez également le voir avec le Gestionnaire des tâches, utilisez View + Sélectionner les colonnes et cochez les objets utilisateur. Regarder l'augmentation du nombre que vous testez l'application devrait fournir une indication correcte.
Une revue de code devrait aller trop loin, il n'y a pas que de nombreuses façons de fuir une fenêtre. Regardez d'abord pour le cas le plus courant, le code qui appelle Controls.Clear () ou Controls.Remove / A () mais ne dispose pas également le contrôle. Cas suivant commun est la classe SystemEvents, vous devez vous désabonner explicitement ses événements. Le reste ne sont pas si faciles à trouver, vous auriez besoin que profileur.
Trouver les poignées vous-même à l'exécution est techniquement possible avec la réflexion. Les poignées sont stockées dans System.Internal.HandleCollector.handleTypes []. Eh bien, sur le plan technique.
Autres conseils
Chaque objet qui implémente IDisposable
a une méthode Dispose
. Cette méthode doit être appelée lorsque l'objet n'est plus nécessaire. Est-il utilisé dans une seule méthode seulement, l'entourer d'une déclaration de using
(appels Dispose
automatiquement). Si elle est une variable membre de votre classe, votre classe doit mettre en œuvre IDisposable
lui-même. FxCop a une règle de vérification pour cela.
Si elles ne sont pas collectées est parce qu'un autre objet est le référencement de vos commandes, ni appeler ni parent disposer la mise à nul suffit. Peut-être que vous attachez à des événements et non dettaching d'eux.
Vérifier spécialement le cas de la fixation à des événements de contrôles ne sont pas contenus par le attacheur, dans ce cas, vous devez toujours détacher des événements lors de l'élimination des contrôles, sinon le contrôle continuera encore à être référencé par le attacheur et donc il ne sera pas libéré