- 
                Notifications
    
You must be signed in to change notification settings  - Fork 2.8k
 
          Fix memory leak with IOptionsMonitor.OnChange and non-singleton registered components (closes #20709 for 13)
          #20722
        
          New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v13/dev
Are you sure you want to change the base?
  
    Fix memory leak with IOptionsMonitor.OnChange and non-singleton registered components (closes #20709 for 13)
  
  #20722
              Conversation
…tered components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes a memory leak issue by properly disposing of IOptionsMonitor.OnChange subscriptions. The changes ensure that change tracking callbacks registered with IOptionsMonitor.OnChange are properly cleaned up when the classes are disposed.
- Converts mutable fields to 
readonlywhere subscriptions are now properly tracked - Captures the 
IDisposablereturned byOnChangeto enable proper cleanup - Implements 
IDisposableon classes that subscribe to option changes to dispose of subscriptions 
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description | 
|---|---|
| src/Umbraco.Web.BackOffice/Controllers/ImagesController.cs | Made _contentSettings field readonly and removed dynamic change tracking | 
| src/Umbraco.Web.BackOffice/Controllers/HelpController.cs | Made _helpPageSettings field readonly and removed dynamic change tracking | 
| src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs | Implemented IDisposable and captured OnChange subscription for proper disposal | 
| src/Umbraco.Infrastructure/PropertyEditors/UploadFileTypeValidator.cs | Implemented IDisposable and captured OnChange subscription for proper disposal | 
| src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs | Implemented IDisposable and captured OnChange subscription for proper disposal | 
| src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs | Implemented IDisposable and captured OnChange subscription for proper disposal | 
| src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs | Implemented IDisposable and captured OnChange subscription for proper disposal | 
        
          
                src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
          
            Show resolved
            Hide resolved
        
              
          
                src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs
          
            Show resolved
            Hide resolved
        
              
          
                src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs
          
            Show resolved
            Hide resolved
        
              
          
                src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs
          
            Show resolved
            Hide resolved
        
      IOptionsMonitor.OnChange and non-singleton registered components.IOptionsMonitor.OnChange and non-singleton registered components (closes #20709 for 13)
      
Prerequisites
Addresses #20709
Description
The linked issue points out a potential problem with how we are handling
IOptionsMonitor.OnChangein components that aren't registered as singletons.Why the current pattern is a concern:
I've checked all instances of this and found only the classes amended in this PR to not be registered as singletons. So other instances are safe. I've resolved by either:
private readonly IDisposable? _optionsChangeSubscription;, assigning it in the constructor, implementingIDisposableand disposing of the reference.OnChange- as we won't need it given controllers are transient.