My understanding is that it is always the subscriber (consumer) of an event that is in risk of being leaked (if the producer lives longer). If I subscribe to an (non-static) event with an anonymous lambda function inside a static method, I should not have to unsubscribe if I want the lambda to live as long as the producer lives?
There is a variant of the question (Does lambda event subscription create memory leak?) with this answer, quoting:
Additionally, that lambda expression isn't using any variables from this, so it would probably be implemented by a static method with no target anyway... I assume the real situation you're concerned with has a more interesting lambda body.
I interpret this to mean that you might have to unsubscribe if the lambda expression is using variables from the target (this
), but in a static method, this
does not exist, hence the question.
The specific code i'm thinking of comes from this answer (see below). The comments to that answer suggests that you have to unsubscribe to avoid memory leaks, but is this really true? What is being leaked exaktly? Another answer to the same question that tried to handle unsubscription, actually added a potential memory leak instead (by storing the eventhandlers in a static dictionary that might not be cleaned up).
private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = source as DataGrid;
ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
// There should be no need to unsubscribe to e.OldValue?
dataGrid.Columns.Clear();
if (columns == null)
{
return;
}
foreach (DataGridColumn column in columns)
{
dataGrid.Columns.Add(column);
}
// This event handler will not keep the columns alive, and the lambda will only be alive as long as the columns is alive?
columns.CollectionChanged += (sender, e2) =>
{
NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
if (ne.Action == NotifyCollectionChangedAction.Reset)
{
// Clear dataGrid.Columns
...
}
else if (ne.Action == NotifyCollectionChangedAction.Add)
{
// Add to dataGrid.Columns
...
}
else if (ne.Action == NotifyCollectionChangedAction.Move)
{
...
}
else if (ne.Action == NotifyCollectionChangedAction.Remove)
{
...
}
else if (ne.Action == NotifyCollectionChangedAction.Replace)
{
...
}
};
}