'WinForms Form is never garbage collected due to reference from ServiceScope
I have a WinForms Form(s) that is not always garbage collected. The form loads quite a bit of data and when it is not garbage collected, it can cause a significant memory leak. This is how I instantiate the form:
// RootForm.cs
private void CreateFormInScope<T>() where T : Form
{
var scope = _serviceProvider.CreateScope();
var form = scope.ServiceProvider.GetRequiredService<T>();
form.FormClosed += (_, _) => scope.Dispose();
form.MdiParent = this;
form.Show();
}
After failing to get anywhere with Visual Studio's diagnostic tools, I tried dotnet dump
. I used dumpheap -type [TYPENAME]
and then used gcroot
on one of the addresses. Here's the end of the root shown:
-> 00000170022A7598 Microsoft.EntityFrameworkCore.Infrastructure.CoreOptionsExtension -> 00000170022A1610 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope -> 00000170022EA2C0 System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib]] -> 0000017002BBDD50 System.Object[] -> 00000170022EF580 FunctionScreens.ProductForm
OK, a scope is holding a reference to the ProductForm. The only scope that could have a reference to it is the child scope I created, right? But that child scope was a local variable, so it shouldn't be referenced by anything, let alone EF Core.
The leak does seem to occur more often if I close the window before async
operations are complete, but I do catch all the exceptions in the event handlers to prevent them from propagating.
Any ideas why it is not being GCed or what I could do to track it down?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|