diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/MainWindowViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/MainWindowViewModel.cs index f73b39c..d1766a5 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/MainWindowViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/MainWindowViewModel.cs @@ -10,7 +10,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.ViewModels; /// /// Main window ViewModel coordinating all panels. /// -public partial class MainWindowViewModel : ObservableObject +public partial class MainWindowViewModel : ObservableObject, IDisposable { private readonly IUiDispatcher _dispatcher; private readonly IOpcUaClientServiceFactory _factory; @@ -411,6 +411,21 @@ public partial class MainWindowViewModel : ObservableObject }); } + /// + /// Detaches the connection-state handler and disposes the OPC UA client service, releasing + /// the session, certificate validator, and any background reconnect resources. + /// + public void Dispose() + { + if (_service != null) + { + _service.ConnectionStateChanged -= OnConnectionStateChanged; + Subscriptions?.Teardown(); + Alarms?.Teardown(); + _service.Dispose(); + } + } + private static string[]? ParseFailoverUrls(string? csv) { if (string.IsNullOrWhiteSpace(csv)) diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs index 108f908..7178ab5 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs @@ -140,7 +140,10 @@ public partial class MainWindow : Window protected override void OnClosing(WindowClosingEventArgs e) { if (DataContext is MainWindowViewModel vm) + { vm.SaveSettings(); + vm.Dispose(); + } base.OnClosing(e); } }