Skip to content

Feature/dotnet10 upgrade - #2

Merged
Nechja merged 6 commits into
mainfrom
feature/dotnet10-upgrade
Feb 7, 2026
Merged

Feature/dotnet10 upgrade#2
Nechja merged 6 commits into
mainfrom
feature/dotnet10-upgrade

Conversation

@Nechja

@Nechja Nechja commented Feb 7, 2026

Copy link
Copy Markdown
Owner

Dotnet 10 upgrade, some clean up.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the OrbitalDocking Avalonia/.NET application and its CI pipeline to .NET 10, along with related dependency updates and a few runtime/test stability tweaks.

Changes:

  • Upgrade projects, CI workflows, and README references from .NET 9 to .NET 10, plus dependency bumps.
  • Add disposal-guard logic to periodic refresh routines in MainWindowViewModel and adjust container stats progress reporting.
  • Update/extend Golden Path tests and introduce a solution file for easier IDE workflows.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
ViewModels/MainWindowViewModel.cs Adds _disposed guards around refresh methods and sets _disposed in Dispose()
ViewModels/ContainerViewModel.cs Switches to a synchronous IProgress<T> implementation for container stats collection
README.md Updates badges and prerequisites to .NET 10
OrbitalDocking.csproj Targets net10.0 and updates package references
OrbitalDocking.Tests/OrbitalDocking.Tests.csproj Targets net10.0 and updates test dependencies
OrbitalDocking.Tests/GoldenPath/ViewModelTests.cs Adds logger mock + default docker service setups; adds dispose-during-refresh test
OrbitalDocking.Tests/GoldenPath/CoreFunctionalityTests.cs Fixes FluentAssertions API usage
Orbital.sln Adds a Visual Studio solution file referencing app + tests
.github/workflows/release.yml Updates CI .NET version to 10.0.x
.github/workflows/build.yml Updates CI .NET version to 10.0.x
Comments suppressed due to low confidence (5)

ViewModels/MainWindowViewModel.cs:904

  • Same disposal race as other refresh methods: _disposed can flip and the semaphore can be disposed between the initial check and WaitAsync(0), which can still throw. Prefer cancel/await in-flight refreshes before disposing semaphores, or avoid disposing the semaphores entirely and just stop scheduling refreshes.
        if (_disposed) return;
        // Try to acquire the semaphore, skip if already refreshing
        if (!await _volumeSemaphore.WaitAsync(0))
            return;

        try
        {
            IsLoading = true;
            var result = await _dockerService.GetVolumesAsync();

ViewModels/MainWindowViewModel.cs:953

  • Same disposal race as other refresh methods: Dispose() can dispose _networkSemaphore after the _disposed check but before WaitAsync(0), leading to ObjectDisposedException. Consider a coordinated shutdown (CTS + await in-flight tasks) and/or not disposing semaphores.
        if (_disposed) return;
        // Try to acquire the semaphore, skip if already refreshing
        if (!await _networkSemaphore.WaitAsync(0))
            return;

        try
        {
            IsLoading = true;
            var result = await _dockerService.GetNetworksAsync();

ViewModels/MainWindowViewModel.cs:1124

  • Setting _disposed = true and immediately disposing subscriptions/cache/semaphores can still race with in-flight refresh tasks (timers/event subscriptions use async callbacks that are not awaited/cancelled). This can cause refresh code to touch _containerCache/collections after they’re disposed. Consider: dispose subscriptions first to stop new triggers, signal cancellation via a viewmodel CTS, then wait for any in-flight refresh operations to finish (or guard post-await work with _disposed checks) before disposing _containerCache/semaphores.
        _disposed = true;
        _themeService.ThemeChanged -= OnThemeChanged;
        _dockerService?.StopMonitoringEvents();
        _subscriptions?.Dispose();
        

ViewModels/MainWindowViewModel.cs:288

  • The _disposed check does not fully prevent ObjectDisposedException: Dispose() can run after the check but before/while WaitAsync(0) executes, and Dispose() currently disposes the semaphores. Consider either (a) not disposing the semaphores at all, or (b) ensuring disposal only happens after all refresh loops have stopped/finished (e.g., cancel with a CTS and await in-flight refreshes), or (c) wrapping WaitAsync/Release in try/catch (ObjectDisposedException) and re-checking _disposed after awaited service calls before touching _containerCache/UI state.
        if (_disposed) return;
        // Try to acquire the semaphore, skip if already refreshing
        if (!await _containerSemaphore.WaitAsync(0))
            return;

        try
        {
            IsLoading = true;
            var result = await _dockerService.GetContainersAsync();

ViewModels/MainWindowViewModel.cs:868

  • Same disposal race as RefreshContainersAsync: between the _disposed check and _imageSemaphore.WaitAsync(0), Dispose() can dispose the semaphore and cause WaitAsync to throw. Also consider re-checking _disposed after await _dockerService.GetImagesAsync() and before Dispatcher.UIThread.InvokeAsync(...) to avoid updating UI after disposal.
        if (_disposed) return;
        // Try to acquire the semaphore, skip if already refreshing
        if (!await _imageSemaphore.WaitAsync(0))
            return;

        try
        {
            IsLoading = true;
            var result = await _dockerService.GetImagesAsync();

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread OrbitalDocking.Tests/GoldenPath/ViewModelTests.cs
@Nechja
Nechja merged commit 4bdafaf into main Feb 7, 2026
1 check passed
@Nechja
Nechja deleted the feature/dotnet10-upgrade branch February 7, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants