Cut idle CPU with a busy cluster feed and many windows open

Found by tracing the app with a fake skimmer feed, a fake rigctld and
eight tool windows open (about 3,500 spots on the bandmap).

- Drop expired spots from the one-second spot timer instead of from each
  window's refresh on the UI thread.
- Bandmap keeps the lists On and All return until the spots change, and
  Near searches only the band the frequency is in.
- The Available window replaces its rows at most every two seconds, the
  Score window redraws at most once a second, and the Telnet list takes
  new lines four times a second at most (RateLimited).
- The bandmap leader line pen is made once.

Idle CPU in that setup went from about 33-70% of one core to about 16-25%.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 13:34:50 +00:00
co-authored by Claude Sonnet 5.5
parent 5e66778301
commit 5f9d186150
8 changed files with 146 additions and 15 deletions
+15 -1
View File
@@ -199,7 +199,7 @@ public sealed class BandmapView : Control
{
IBrush colour = ColourOf(label.Spot);
context.DrawLine(
new Pen(Opaque(ink, 0.55), 1),
LeaderPen(ink),
new Point(ScaleX + 2, label.MarkY),
new Point(LabelX - 2, label.LabelY + (LabelHeight / 2)));
context.DrawText(
@@ -285,6 +285,20 @@ public sealed class BandmapView : Control
private IBrush Foreground() =>
this.FindResource("FormForeground") as IBrush ?? Brushes.Gray;
private Pen? leaderPen;
private IBrush? leaderInk;
/// The line from the scale to a callsign. Every label has the same one.
private Pen LeaderPen(IBrush ink)
{
if (leaderPen is null || !ReferenceEquals(leaderInk, ink))
{
leaderPen = new Pen(Opaque(ink, 0.55), 1);
leaderInk = ink;
}
return leaderPen;
}
private readonly Dictionary<(IBrush Ink, double Opacity), IBrush> faded = [];
/// Kept, so the same brush comes back each time and the text drawn with it