Skip to content

[Code Quality] LogsViewModel — CTS + Cleanup() without IDisposable (4th VM with pattern from #716) #732

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Info
File: src/Servy.Manager/ViewModels/LogsViewModel.cs

Description:
LogsViewModel inherits directly from INotifyPropertyChanged (not ServiceSearchViewModelBase). It holds a CancellationTokenSource (line 34) and exposes a Cleanup() method (line 411) that atomically swaps and disposes the CTS. It does not implement IDisposable.

This is the exact pattern called out in #716 for ConsoleViewModel, PerformanceViewModel, and DependenciesViewModel — if the host forgets to call Cleanup() on VM replacement (tab-swap edge cases, navigation exceptions), the CTS is leaked. #716 already proposes making ServiceSearchViewModelBase : IDisposable, but LogsViewModel does not inherit from that base, so it needs its own fix.

public class LogsViewModel : INotifyPropertyChanged   // no IDisposable
{
    private CancellationTokenSource _cancellationTokenSource;   // line 34
    // ...
    public void Cleanup()                                       // line 411
    {
        var oldCts = Interlocked.Exchange(ref _cancellationTokenSource, null);
        if (oldCts != null) { try { oldCts.Cancel(); } catch (ObjectDisposedException) { }
                              finally { oldCts.Dispose(); } }
    }
}

Suggested fix:
Promote Cleanup() to an IDisposable.Dispose() implementation (keeping Cleanup() as an alias if needed for backwards compat), and have every place that currently calls Cleanup() switch to using/Dispose(). Consider applying the same pattern consistency review to any other VM that holds a CTS or timer but doesn't derive from ServiceSearchViewModelBase.

If the fix for #716 is to make the base class IDisposable, there is still value in making LogsViewModel : IDisposable explicitly for the same reason.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions