Toutes les idées sur la façon d'écrire une règle d'analyse statique (FXCop) pour faire en sorte que les délégués d'événements sont supprimés

StackOverflow https://stackoverflow.com/questions/854716

Question

Nous allons à travers une grande analyse des fuites de mémoire et ont trouvé un des facteurs a été la non suppression des délégués sur les événements à l'origine des objets à ne pas être GCed assez rapidement (ou parfois pour toujours).

Est-ce que quelqu'un a des idées quant à la façon d'écrire une règle FXCop pour nous assurer que nous avons les délégués sont retirés de gestionnaires?

Je viens de voir ce et en tant que telle I » ll y demander pour plus d'informations.

Était-ce utile?

La solution

Ok, à côté du problème de la mise en œuvre du contrôle réel (à mon avis ce qui est très semblable à un la couverture et donc pas pratique) - est ici la façon d'écrire une nouvelle règle FxCop il:

Tout d'abord quelques articles qui m'a aidé une fois:

La mise en œuvre d'une règle simple est pas une grosse affaire. Dans votre projet, vous avez besoin d'un fichier rules.xml comme une ressource intégrée (voir ici ). Vous dérivez votre classe de et ajoutez votre BaseIntrospectionRule code Check () - Méthode:

public override ProblemCollection Check( TypeNode typeNode )
{
  if( type.IsPublic )
  {
    Problems.Add( new Problem( ... ) );
  }
  return Problems;
}

Je l'ai fait il y a quelques temps. J'espère que cela fonctionne encore comme décrit:)

Autres conseils

Vous devez être plus précis. Vous n'avez pas besoin de vérifier que tous les délégués de l'événement ont été désinscrit, parce que dans un cas commun un abonné vit sa vie plus courte qu'un éditeur. Et une fuite de mémoire se produit uniquement lorsque votre abonné semble être à long terme qu'un éditeur, d'où il est une référence, ce qui empêche GC de recueillir l'objet d'éditeur.

Maintenant, nous devons vérifier que si vous vous abonnez à un événement sur un objet relativement courte durée de vie, vous vous désabonnez éventuellement.

Un heuristiques je peux trouver dans ce cas: analyser tous les objets locaux variables (dont la portée par le bloc de code actuel {}) et tous les objets que vous disposez explicitement. Pour chaque événement sur ces objets compter le nombre de fois que vous abonner et le nombre de fois que vous désabonnez. Si le premier nombre est supérieur émet alors un avertissement.

Bien sûr, qui ne couvre pas tous les cas, mais je suppose que pas d'approche statique peut couvrir tous les cas ce problème, vous avez besoin d'une méthode qui est assez bon.

Je ne vais pas parler des avantages de l'analyse dynamique et le code en revue ici car il est un sujet distinct, non lié à la question.

Pouvez-vous forcer une règle que tous les abonnements d'événements devraient être traités par WeakReferences? Je pense cela devrait être plus facile à mettre en œuvre que d'avoir à analyser le flux réel de votre programme.

Est-il sûr d'assumer les objets implémentant les gestionnaires ont en quelque sorte des références à l'objet avec les événements? Si tel est le cas, vous êtes mieux de trouver comment briser le cercle vicieux d'une autre manière.

Nous avons eu quelque chose de semblable se passe un certain temps avec des gestionnaires d'événements sur les pages ASP.NET. Les objets mis en œuvre les gestionnaires ont également des références aux pages. Après avoir rompu le plus grand nombre des liens architectually que nous le pouvions, les quelques restes ont été changés pour WeakReferences. Pas plus de problèmes de mémoire!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top