refactor: 插件窗体由 static 单例状态改为实例字段(对齐 TextViewer)

将 10 个 CycleGUI 窗体/管理器从进程级 static 单例状态改为实例字段 + 实例方法,
消除本地端/Web 端共享同一可变状态的隐患(对齐 TextViewer 正例)。

每个类保留一个 private static _instance 单实例持有者;静态入口 Open()/OpenViewer()
与实例 Show() 均转发到该实例,调用方零改动、单实例“置前”行为不变。

涉及:ChargeStationManagementForm、ChargeStrategyConfigForm、CommunicationMonitorForm、
AlarmConfigManagementForm、ButtonBoxManager、DoorManager、DoorMonitor、
LoopViewer、DeliveryViewer、TrafficInterlockViewer。

构建:dotnet build StandardScene.sln --no-incremental → 0 错误,30 警告(与基线一致,无新增)。
This commit is contained in:
zhaowei.huang
2026-06-26 15:31:02 +08:00
parent a0dc1e6cd0
commit 54cda958db
10 changed files with 297 additions and 257 deletions
@@ -24,33 +24,37 @@ namespace StandardScene.Charge
private const int StatsRefreshMs = 500;
private const string TableId = "comm-monitor-msgs";
private static readonly Color SendRowColor = Color.FromArgb(232, 245, 233);
private static readonly Color ReceiveRowColor = Color.FromArgb(227, 242, 253);
private static readonly Color SelectedRowColor = Color.FromArgb(255, 249, 196);
private readonly Color SendRowColor = Color.FromArgb(232, 245, 233);
private readonly Color ReceiveRowColor = Color.FromArgb(227, 242, 253);
private readonly Color SelectedRowColor = Color.FromArgb(255, 249, 196);
private static readonly CommunicationMessageService MessageService = CommunicationMessageService.Instance;
private readonly CommunicationMessageService MessageService = CommunicationMessageService.Instance;
private static Panel _panel;
private static bool _subscribed;
private static bool _paused;
private static int _selectedIpIndex;
private static string[] _ipOptions = { "全部" };
private static int _selectedRowIndex = -1;
private static string _parsedText = "";
private static string _statsText = "";
private Panel _panel;
private bool _subscribed;
private bool _paused;
private int _selectedIpIndex;
private string[] _ipOptions = { "全部" };
private int _selectedRowIndex = -1;
private string _parsedText = "";
private string _statsText = "";
private static List<CommunicationMessage> _displayMessages = new List<CommunicationMessage>();
private static readonly Queue<CommunicationMessage> PendingMessages = new Queue<CommunicationMessage>();
private static readonly object PendingLock = new object();
private List<CommunicationMessage> _displayMessages = new List<CommunicationMessage>();
private readonly Queue<CommunicationMessage> PendingMessages = new Queue<CommunicationMessage>();
private readonly object PendingLock = new object();
private static DateTime _lastStatsRefresh = DateTime.MinValue;
private static bool _pendingStatsRefresh;
private DateTime _lastStatsRefresh = DateTime.MinValue;
private bool _pendingStatsRefresh;
/// <summary>打开(或置前)通讯监控面板。兼容原 <c>new CommunicationMonitorForm().Show()</c> 调用方式。</summary>
public void Show() => Open();
/// <summary>打开(或置前)通讯监控面板。</summary>
public static void Open()
public static void Open() => (_instance ??= new CommunicationMonitorForm()).OpenCore();
private static CommunicationMonitorForm _instance;
private void OpenCore()
{
if (_panel != null)
{
@@ -169,7 +173,7 @@ namespace StandardScene.Charge
});
}
private static void Subscribe()
private void Subscribe()
{
if (_subscribed)
return;
@@ -177,7 +181,7 @@ namespace StandardScene.Charge
_subscribed = true;
}
private static void Unsubscribe()
private void Unsubscribe()
{
if (!_subscribed)
return;
@@ -187,7 +191,7 @@ namespace StandardScene.Charge
PendingMessages.Clear();
}
private static void OnMessageAdded(object sender, CommunicationMessage message)
private void OnMessageAdded(object sender, CommunicationMessage message)
{
if (!_subscribed || message == null)
return;
@@ -199,7 +203,7 @@ namespace StandardScene.Charge
}
/// <summary>定时批量刷新 UI,避免每条报文都抢占渲染线程。</summary>
private static void FlushPendingBatch()
private void FlushPendingBatch()
{
if (_paused)
return;
@@ -236,7 +240,7 @@ namespace StandardScene.Charge
RequestStatisticsRefresh();
}
private static void InsertMessageAtTop(CommunicationMessage msg)
private void InsertMessageAtTop(CommunicationMessage msg)
{
_displayMessages.Insert(0, msg);
while (_displayMessages.Count > MaxDisplayRows)
@@ -246,7 +250,7 @@ namespace StandardScene.Charge
_selectedRowIndex++;
}
private static void ReloadFromService()
private void ReloadFromService()
{
try
{
@@ -267,7 +271,7 @@ namespace StandardScene.Charge
}
}
private static void RefreshIpFilter()
private void RefreshIpFilter()
{
try
{
@@ -302,7 +306,7 @@ namespace StandardScene.Charge
}
}
private static void EnsureIpInFilter(string ipAddress)
private void EnsureIpInFilter(string ipAddress)
{
if (string.IsNullOrWhiteSpace(ipAddress))
return;
@@ -315,7 +319,7 @@ namespace StandardScene.Charge
_ipOptions = list.ToArray();
}
private static string SelectedIpFilter()
private string SelectedIpFilter()
{
if (_ipOptions == null || _ipOptions.Length == 0)
return "全部";
@@ -324,13 +328,13 @@ namespace StandardScene.Charge
return _ipOptions[_selectedIpIndex];
}
private static void RequestStatisticsRefresh()
private void RequestStatisticsRefresh()
{
_pendingStatsRefresh = true;
}
/// <summary>统计信息低频刷新(500ms)。</summary>
private static void MaybeRefreshStatistics()
private void MaybeRefreshStatistics()
{
if (!_pendingStatsRefresh)
return;
@@ -342,7 +346,7 @@ namespace StandardScene.Charge
UpdateStatistics(_displayMessages.Count);
}
private static void UpdateStatistics(int displayCount)
private void UpdateStatistics(int displayCount)
{
try
{
@@ -364,14 +368,14 @@ namespace StandardScene.Charge
}
}
private static string TruncateRawData(string rawData, int maxLen = 48)
private string TruncateRawData(string rawData, int maxLen = 48)
{
if (string.IsNullOrEmpty(rawData))
return "";
return rawData.Length <= maxLen ? rawData : rawData.Substring(0, maxLen) + "…";
}
private static string BuildParsedText(CommunicationMessage message)
private string BuildParsedText(CommunicationMessage message)
{
if (message == null)
return "";