C# – BindingList memory leak

bindinglistc++clrinotifypropertychangedmemory-leaks

My application uses a custom List that inherits from Bindinglist which is then bound to all the UI controls. The list is a collection of baseobjects which implements INotifyPropertyChanged. I suspected a memory leak and profiled my application using
memprofiler which confirmed that that all my lists are never disposed and that they are clinging on because they are subscribed to the propertyChanged eventhandlers of the bindinglist.

Here is the sample of my objects

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);
     }
}

Here is the allocation stack from the profiler

[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

Can someone help me in getting the lists disposed.

Thanks all


Henk, you were right. The problem was not with the code I mentioned, instead I have narrowed it down to delegates which are preventing my form from being disposed. I am working on a sample to replicate the problem which I will upload to the site. Thanks

Best Solution

I don't believe the problem is in the code shown here, the event in BaseObject only causes outgoing references (to the subscribers). It gets a bit iffy with the hiding of Add/Remove and the BaseList class. Could it be that the < Custom Code> interferes with subscribing/unsubscribing to the PropertyChanged event?

And is where T:BaseList a typo (I would expect baseObject here) or is there another class involved?

On a side note, I am a bit puzzled by the 'virtual' in

public virtual event PropertyChangedEventHandler PropertyChanged;

I am not sure if you have a purpose for that, I think it should go.

And the BaseBusinessList should probably Implement IRaiseItemChangedEvents