HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Possible memory leak with WPF Custom Control?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
controlwithwpfcustompossibleleakmemory

Problem

I might have a potential memory leak with my custom control. Do I actually have one?

```
public interface IAlertable : INotifyPropertyChanged { ... }

public sealed class AlertButton : Button
{
private static readonly DependencyPropertyKey HasAlertPropertyKey = DependencyProperty.RegisterReadOnly("HasAlert", typeof(bool), typeof(AlertButton),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.None, null));

public static readonly DependencyProperty HasAlertProperty = HasAlertPropertyKey.DependencyProperty;

public static readonly DependencyProperty AlertContextProperty = DependencyProperty.Register("AlertContext", typeof(IAlertable), typeof(AlertButton),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, OnAlertContextChanged, null, false, UpdateSourceTrigger.PropertyChanged));

static AlertButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AlertButton), new FrameworkPropertyMetadata(typeof(AlertButton)));
}

private PropertyChangedEventHandler PropertyChangedEventHandler { get; set; }

public bool HasAlert
{
get { return (bool)GetValue(HasAlertProperty); }
protected set { SetValue(HasAlertPropertyKey, value); }
}

public IAlertable AlertContext
{
get { return (IAlertable )GetValue(AlertContextProperty); }
set { SetValue(AlertContextProperty, value); }
}

private static void OnAlertContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = (AlertButton)d;

obj.OnAlertContextChanged((IAlertable)e.OldValue, (IAlertable)e.NewValue);
}

private void OnAlertContextChanged(IAlertable prev, IAlertable curr)
{
if (prev != null)
{
UnhookEvents(prev);
}
if (curr != null)
{
HookEvents(curr);
}
}

private void UnhookEvents(IAlertable context)
{
var handler = PropertyC

Solution

Yes, you are correct, in some cases ICommand can leak memory too! Usually it does not happen, because most implementations of ICommand either utilize CommandManager (which uses weak references) or do not care about CanExecute state and therefore use empty CanExecuteChanged event, which does not hold any references at all. But if you implement CanExecuteChanged as strong event, ICommand will cause memory leak.

In your case the simplest solution would probably be to additionally UnhookEvents when control is unloaded, and to HookEvents when it is loaded.

Alternatively, you can use weak events pattern as Zache suggested.

Context

StackExchange Code Review Q#54191, answer score: 3

Revisions (0)

No revisions yet.