Skip to content

Commit cb5bc9a

Browse files
Fix Dashboard auto-refresh: async loop, survive tab close, prevent legend duplication
Replace DispatcherTimer with async Task.Delay loop to prevent priority starvation under heavy UI load. Don't cancel the loop on Unloaded (WPF fires Unloaded on tab switch/close, not just control destruction). Catch OperationCanceledException from SQL queries without killing the loop. Skip auto-refresh ticks while a full refresh is in progress to prevent concurrent chart rendering that duplicates legends. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a2c0b93 commit cb5bc9a

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

Dashboard/ServerTab.xaml.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ private async void StartAutoRefreshLoop(int intervalSeconds)
375375
{
376376
await Task.Delay(TimeSpan.FromSeconds(intervalSeconds), cts.Token);
377377
if (cts.Token.IsCancellationRequested) break;
378+
if (_isRefreshing) continue;
378379

379380
try
380381
{
@@ -384,6 +385,11 @@ private async void StartAutoRefreshLoop(int intervalSeconds)
384385
FooterText.Text = $"Last refresh: {DateTime.Now:yyyy-MM-dd HH:mm:ss} | Server: {_serverConnection.DisplayName}";
385386
Logger.Info($"Auto-refresh completed in {sw.ElapsedMilliseconds}ms for {_serverConnection.DisplayName}");
386387
}
388+
catch (OperationCanceledException) when (!cts.Token.IsCancellationRequested)
389+
{
390+
// SQL query cancelled or timed out, but our loop CTS is still alive — keep going
391+
Logger.Error($"Auto-refresh query cancelled for {_serverConnection.DisplayName}, continuing loop");
392+
}
387393
catch (Exception ex) when (ex is not OperationCanceledException)
388394
{
389395
Logger.Error($"Auto-refresh error: {ex.Message}", ex);
@@ -393,13 +399,15 @@ private async void StartAutoRefreshLoop(int intervalSeconds)
393399
}
394400
catch (OperationCanceledException)
395401
{
396-
// Normal shutdown
402+
Logger.Info($"Auto-refresh loop stopped for {_serverConnection.DisplayName}");
397403
}
398404
}
399405

400406
private void ServerTab_Unloaded(object sender, RoutedEventArgs e)
401407
{
402-
_autoRefreshCts?.Cancel();
408+
// Don't cancel auto-refresh on tab switch — WPF fires Unloaded when
409+
// a TabItem is deselected, not just when the control is destroyed.
410+
// The loop is lightweight and should keep ticking in the background.
403411
_autoRefreshTimer?.Stop();
404412
_autoRefreshTimer = null;
405413

0 commit comments

Comments
 (0)