From 07b536895a861a77f2833cb977833114aef165ea Mon Sep 17 00:00:00 2001 From: zhaotielin Date: Mon, 13 Jul 2026 03:51:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=8F=B0=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SSPCTester.UI/App.xaml.cs | 5 +++- .../ViewModels/ExperimentConsoleViewModel.cs | 23 +++++++++++++++---- SSPCTester.UI/ViewModels/TestHostViewModel.cs | 5 +++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/SSPCTester.UI/App.xaml.cs b/SSPCTester.UI/App.xaml.cs index 83a2f78..709ce45 100644 --- a/SSPCTester.UI/App.xaml.cs +++ b/SSPCTester.UI/App.xaml.cs @@ -180,7 +180,10 @@ public partial class App : Application services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + // The experiment console controls application-wide hardware and is not + // owned by a project. Keep one instance so switching project pages does + // not replace its state or interrupt its refresh loop. + services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/SSPCTester.UI/ViewModels/ExperimentConsoleViewModel.cs b/SSPCTester.UI/ViewModels/ExperimentConsoleViewModel.cs index 4a31b11..c8658de 100644 --- a/SSPCTester.UI/ViewModels/ExperimentConsoleViewModel.cs +++ b/SSPCTester.UI/ViewModels/ExperimentConsoleViewModel.cs @@ -17,6 +17,7 @@ public partial class ExperimentConsoleViewModel : ObservableObject private readonly UserSettingsStore _settingsStore; private readonly UiLogSink _log; private readonly object _pollLock = new(); + private readonly HashSet _activeHosts = new(ReferenceEqualityComparer.Instance); private CancellationTokenSource? _pollCts; private Task? _pollTask; @@ -113,12 +114,24 @@ public partial class ExperimentConsoleViewModel : ObservableObject LoadCurrentSetpoint = value.Current; } - public void SetActive(bool active) + public void SetActive(object host, bool active) { - if (active) - StartPolling(); - else - StopPolling(); + ArgumentNullException.ThrowIfNull(host); + + lock (_pollLock) + { + if (active) + { + _activeHosts.Add(host); + StartPolling(); + } + else + { + _activeHosts.Remove(host); + if (_activeHosts.Count == 0) + StopPolling(); + } + } } [RelayCommand] diff --git a/SSPCTester.UI/ViewModels/TestHostViewModel.cs b/SSPCTester.UI/ViewModels/TestHostViewModel.cs index 339c645..867a14a 100644 --- a/SSPCTester.UI/ViewModels/TestHostViewModel.cs +++ b/SSPCTester.UI/ViewModels/TestHostViewModel.cs @@ -49,6 +49,9 @@ public partial class TestHostViewModel : ObservableObject private void UpdateConsoleActive() { - Console.SetActive(_isViewActive && SelectedTabIndex == 0); + // Identify this host when acquiring/releasing console polling. During a + // project switch WPF can load the new host before unloading the old one; + // the old host must not stop the shared console on behalf of the new host. + Console.SetActive(this, _isViewActive && SelectedTabIndex == 0); } }