tags:

views:

74

answers:

0

Dear all, I have a problem and I hope you can help me, guys! We implement a software which have to register weak event listeners on objects. The reason is that we have to react on some events, where we cannot know if the event source object still exists.

During the implementation, I found a potential memory leak in .NET FW's WeakEventManager class. To analyze the problem, I created a simple WPF application, because they use its features.

Consider the following code:

public partial class Window1 : Window  {
private ManualResetEvent _mre = new ManualResetEvent(false);
private Thread _switcher;
private Random _rnd = new Random();

private void Switcher()
{
  while (!_mre.WaitOne(10))
  {
    var dc = new ObservableCollection<int>();
    for (int i = 0; i < 100; ++i)
      dc.Add(_rnd.Next());
    this.Dispatcher.Invoke(new Action<object>(SetContext), dc);
  }
}

private void SetContext(object param)
{
  this.DataContext = param;
}

public Window1()
{
  InitializeComponent();
  _switcher = new Thread(new ThreadStart(Switcher));
  _switcher.Start();
}

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
  _mre.Set();
  _switcher.Join();
}

}

The XAML contains only a ListView having its ItemsSource binded to '.'.

It is clear that the collection removed from DataContext has to be released and the new DataContext collection will have the same size as the previous one had -> memory consumption should be constant. However if you run this application by using a profiler, you can clearly observe the memory leak.

In the 28th second the WeakReference objects consumed 12% (118 536 bytes) of the memory usage. (This number would be much more if I would consider the other objects created by the weak event manager.)

After 16 minutes it consumed 50% (10 452 576 bytes)!!!

Do anyone have an explanation and/or a workaround for us?

Thanks for every comment!

Best wishes: kkb