diff --git a/Dashboard/ServerTab.xaml.cs b/Dashboard/ServerTab.xaml.cs index a67daf8..4f990bf 100644 --- a/Dashboard/ServerTab.xaml.cs +++ b/Dashboard/ServerTab.xaml.cs @@ -375,6 +375,7 @@ private async void StartAutoRefreshLoop(int intervalSeconds) { await Task.Delay(TimeSpan.FromSeconds(intervalSeconds), cts.Token); if (cts.Token.IsCancellationRequested) break; + if (_isRefreshing) continue; try { @@ -384,6 +385,11 @@ private async void StartAutoRefreshLoop(int intervalSeconds) FooterText.Text = $"Last refresh: {DateTime.Now:yyyy-MM-dd HH:mm:ss} | Server: {_serverConnection.DisplayName}"; Logger.Info($"Auto-refresh completed in {sw.ElapsedMilliseconds}ms for {_serverConnection.DisplayName}"); } + catch (OperationCanceledException) when (!cts.Token.IsCancellationRequested) + { + // SQL query cancelled or timed out, but our loop CTS is still alive — keep going + Logger.Error($"Auto-refresh query cancelled for {_serverConnection.DisplayName}, continuing loop"); + } catch (Exception ex) when (ex is not OperationCanceledException) { Logger.Error($"Auto-refresh error: {ex.Message}", ex); @@ -393,13 +399,15 @@ private async void StartAutoRefreshLoop(int intervalSeconds) } catch (OperationCanceledException) { - // Normal shutdown + Logger.Info($"Auto-refresh loop stopped for {_serverConnection.DisplayName}"); } } private void ServerTab_Unloaded(object sender, RoutedEventArgs e) { - _autoRefreshCts?.Cancel(); + // Don't cancel auto-refresh on tab switch — WPF fires Unloaded when + // a TabItem is deselected, not just when the control is destroyed. + // The loop is lightweight and should keep ticking in the background. _autoRefreshTimer?.Stop(); _autoRefreshTimer = null;