-
-
Notifications
You must be signed in to change notification settings - Fork 885
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
OnLoaded method of the ListView from WPF-UI uses DependencyPropertyDescriptor
to invoke AddValueChanged
, but never unregisters the event handler using RemoveValueChanged
, which leads to a memory leak because a strong refence is created to the component.
wpfui/src/Wpf.Ui/Controls/ListView/ListView.cs
Lines 67 to 78 in 4ac9686
private void OnLoaded(object sender, RoutedEventArgs e) | |
{ | |
Loaded -= OnLoaded; // prevent memory leaks | |
// Setup initial ViewState and hook into View property changes | |
var descriptor = DependencyPropertyDescriptor.FromProperty( | |
System.Windows.Controls.ListView.ViewProperty, | |
typeof(System.Windows.Controls.ListView) | |
); | |
descriptor?.AddValueChanged(this, OnViewPropertyChanged); | |
UpdateViewState(); // set the initial state | |
} |
To Reproduce
An instance of a ListView
from WPF-UI stays in memory forever because a strong reference to the component is created and never removed.
public class UnitTest1
{
[Fact]
public Task TestWpfUiControlsListView()
{
return TestListViewMemoryLeakAsync<Wpf.Ui.Controls.ListView>();
}
[Fact]
public Task TestSystemWindowsControlListView()
{
return TestListViewMemoryLeakAsync<System.Windows.Controls.ListView>();
}
public async Task TestListViewMemoryLeakAsync<T>() where T : ListView, new()
{
WeakReference? wr = null;
await StartSTATask(() =>
{
var listView = new T();
wr = new WeakReference(listView);
listView.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));
listView.RaiseEvent(new RoutedEventArgs(FrameworkElement.UnloadedEvent));
});
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
Assert.NotNull(wr);
Assert.False(wr.IsAlive);
}
private static Task StartSTATask(Action action)
{
var tcs = new TaskCompletionSource<object>();
var thread = new Thread(() =>
{
try
{
action();
tcs.SetResult(new object());
}
catch (Exception e)
{
tcs.SetException(e);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
}
Expected behavior
ListView
should subscribe to Unloaded
event and call RemoveValueChanged
.
Screenshots
No response
OS version
All.
.NET version
All.
WPF-UI NuGet version
3.0.5 - latest (4.0.0-rc.2)
Additional context
No response
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working