2009-07-05 8 views
1

Mon application utilise une liste personnalisée qui hérite de Bindinglist qui est ensuite liée à tous les contrôles de l'interface utilisateur. La liste est une collection de baseobjects qui implémente INotifyPropertyChanged. J'ai suspecté une fuite de mémoire et profilé mon application en utilisant memprofiler qui a confirmé que toutes mes listes ne sont jamais éliminées et qu'elles sont accrochées car elles sont abonnées aux gestionnaires d'événements propertyChanged de la liste de liaison.BindingList fuite de mémoire

Voici l'exemple de mes objets

public abstract class BaseObject:IDataErrorInfo,INotifyPropertyChanged,ICloneable 
{ 
private Guid _Id = Guid.NewGuid(); 
public virtual Guid ID 
{ 
    get { return this._Id; } 
    set { this._Id = value; this.OnPropertyChange(new 
          PropertyChangedEventArgs(propertyName)); } 
} 

[field:NonSerialized] 
public virtual event PropertyChangedEventHandler PropertyChanged; 
protected virtual void OnPropertyChange(PropertyChangedEventArgs e) 
{ 
    if (this.PropertyChanged != null) this.PropertyChanged(this, e); 
} 
} 

[Serializable] 
public class BaseList<T> :BindingList<T>,ICloneable where T:BaseObject 
{ 
public new void Add(T item) 
{  
    <Custom code> 
    base.Add(item); 
    } 

public new void Remove(T item) 
{ 
    <Custom Code> 
    base.Remove(item); 
    } 
} 

Voici la pile d'allocation du profileur

[Skipped frame(s)] 
mscorlib!System.MulticastDelegate.CombineImpl(Delegate) 
mscorlib!System.Delegate.Combine(Delegate, Delegate) 
<AppName>.Data!<AppName>.Data.BaseObject.add_PropertyChanged( 
       PropertyChangedEventHandler) 

[Skipped frame(s)] 
System!System.ComponentModel.BindingList<T>.InsertItem(int, T) 
mscorlib!System.Collections.ObjectModel.Collection<T>.Add(T) 
<AppName>.Data.BaseList<T>.Add(T) BaseList.cs 
<AppName>.UI.Forms.Form1.GetData() Form1 
<AppName>.UI.Forms.Form1.Initialize() Form1 
<AppName>.UI.Forms.Form1.RunAsyncComplete() Form1 

quelqu'un peut me aider à obtenir les listes disposées.

Merci à tous


Henk, vous aviez raison. Le problème ne résidait pas dans le code que j'ai mentionné, mais je l'ai réduit aux délégués qui empêchent que mon formulaire soit éliminé. Je travaille sur un échantillon pour reproduire le problème que je vais télécharger sur le site. Merci

Répondre

2

Je ne crois pas que le problème est dans le code montré ici, l'événement dans BaseObject ne cause que des références sortantes (aux abonnés). Il devient un peu incertain avec le masquage de Ajouter/Supprimer et la classe BaseList. Se pourrait-il que le code personnalisé < interfère avec l'abonnement/désabonnement à l'événement PropertyChanged?

Et est where T:BaseList une faute de frappe (je m'attendrais à baseObject ici) ou y at-il une autre classe impliquée?

Sur une note côté, je suis un peu perplexe par le « virtuel » dans

public virtual event PropertyChangedEventHandler PropertyChanged; 

Je ne sais pas si vous avez un but pour cela, je pense qu'il devrait aller.

Et la BaseBusinessList devrait probablement implémenter IRaiseItemChangedEvents