Skip to content

Memory leak in FluentWindow #1648

@thecco

Description

@thecco

Describe the bug

A memory leak occurs in FluentWindow. The window instance and its DataContext are not collected by the GC because an anonymous delegate is subscribed to the static event ApplicationThemeManager.Changed without being unsubscribed. This results in a continuous increase in the EventHandler count.

To Reproduce

  1. Create a Window class inheriting from FluentWindow and add a finalizer with a Debug.WriteLine to track its destruction:
public class TestWindow : FluentWindow
{
    ~TestWindow() 
    {
        Debug.WriteLine("Destruction");
    }
}
  1. Open and close the TestWindow multiple times.
  2. Perform a manual Garbage Collection (GC) and check the Output Window.
  3. The finalizer is never called (the "Destruction" log does not appear), and the EventHandler count increases continuously in the memory profiler.

Expected behavior

When the window is closed, all event subscriptions—especially those to static events—should be released so the FluentWindow and its ViewModel can be garbage collected.

Screenshots

No response

OS version

Windows 11 25H2 26200.7462

.NET version

.NET9

WPF-UI NuGet version

4.20

Additional context

I have implemented a temporary workaround for this issue as follows

protected override void OnClosed(EventArgs e)
{
    base.OnClosed(e);

    FixBug();
}
private void FixBug()
{
    Type? type = typeof(ApplicationThemeManager);
    FieldInfo? eventField = type.GetField("Changed", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance);

    if (eventField != null)
    {
        MulticastDelegate? eventDelegate = eventField.GetValue(null) as MulticastDelegate;

        if (eventDelegate != null)
        {
            Delegate[] invocationList = eventDelegate.GetInvocationList();

            foreach (Delegate handler in invocationList)
            {
                if (handler.Target == this)
                {
                    ApplicationThemeManager.Changed -= (ThemeChangedEvent)handler;
                }
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions