Control._reflectParent is not updated when Parent changes (memory leak)
See original GitHub issue.NET version
.NET 7.0.5 (latest public release)
Did it work in .NET Framework?
No
Did it work in any of the earlier releases of .NET Core or .NET 5+?
I don’t think this is a regression, it was probably always like this. I’ve never needed to worry about this in the past – my use of Controls did not include reparenting until now.
Issue description
The Control._reflectParent field points to a control’s parent control. It is updated by calling set_ReflectParent via
UpdateReflectParent(), which is called by CreateHandle(), Dispose(bool), and OnHandleDestroyed(EventArgs).
Notably absent from that list is OnParentChanged() (or any method to that effect). This means that _reflectParent is not set to null when a control is removed from its parent, nor is it updated when the control is added to a new parent.
Here is the ILSpy analysis tree for _reflectParent :
This results in a memory leak if a control is re-used, which is something I’m doing in Paint.NET to implement a large memory use optimization. This optimization depends on a control’s Handle not being recreated during a reparenting operation (which does work fine).
In SciTech Memory Profile we can see this clearly. In this case, the CanvasControlImpl (child) has been removed from the CanvasControl (parent), but it (child) still has a reference to it (parent) whether it (child) has been reparented yet or not. The yellow exclamation mark indicates that CanvasControl is disposed.
I don’t know if there are other behavioral bugs that result from this – ReflectParent only seems to be read by OnParentHandleRecreated().
Steps to reproduce
- Create two
Controls,c1andc2 - Add
c1to aForm - Add
c2as a child ofc1 - Show the form
- Remove
c2fromc1 - Inspect
c2._reflectParent. It should benull, but it still referencesc1.
Issue Analytics
- State:
- Created 4 months ago
- Reactions:2
- Comments:5 (3 by maintainers)

Top Related StackOverflow Question
@Nora-Zhou01 there really isn’t much of value you can do to repro- I added a unit test that does this.
Apparently, I didn’t mark my PR correctly. I’m closing this now.
I’m not sure I understand … @JeremyKuhne landed a fix for this in #9159. What is it exactly that you need from me? Like a minimal repro? As in, a Visual Studio project you can run that will reproduce the issue?