using Microsoft.AspNetCore.Components; namespace MxGateway.Server.Dashboard.Components; public abstract class DashboardPageBase : ComponentBase, IAsyncDisposable { private readonly CancellationTokenSource _disposeCancellation = new(); private Task? _watchTask; [Inject] protected IDashboardSnapshotService SnapshotService { get; set; } = null!; protected DashboardSnapshot? Snapshot { get; private set; } protected override void OnInitialized() { _watchTask = WatchSnapshotsAsync(); } public async ValueTask DisposeAsync() { await _disposeCancellation.CancelAsync().ConfigureAwait(false); if (_watchTask is not null) { await _watchTask.ConfigureAwait(false); } _disposeCancellation.Dispose(); GC.SuppressFinalize(this); } private async Task WatchSnapshotsAsync() { try { await foreach (DashboardSnapshot snapshot in SnapshotService .WatchSnapshotsAsync(_disposeCancellation.Token) .ConfigureAwait(false)) { Snapshot = snapshot; await InvokeAsync(StateHasChanged).ConfigureAwait(false); } } catch (OperationCanceledException) when (_disposeCancellation.IsCancellationRequested) { } } }