|
|
@@ -401,51 +401,192 @@ public partial class App : Application
|
|
|
|
|
|
private void StopServices()
|
|
|
{
|
|
|
+ Serilog.Log.Information("=== StopServices 开始 ===");
|
|
|
+ var sw = System.Diagnostics.Stopwatch.StartNew();
|
|
|
+
|
|
|
// 取消事件订阅(防止已释放的 hub 收到回调)
|
|
|
PlcPollingService.Instance.DataUpdated -= OnDataUpdatedForBroadcast;
|
|
|
AlarmService.Instance.AlarmRaised -= OnAlarmRaisedForBroadcast;
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] 事件订阅已取消", sw.ElapsedMilliseconds);
|
|
|
+
|
|
|
+ // 1. 先停止看门狗(防止它尝试重启其他正在停止的服务)
|
|
|
+ try
|
|
|
+ {
|
|
|
+ WatchdogService.Instance.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] WatchdogService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] WatchdogService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
|
|
|
- _hubClient?.Dispose();
|
|
|
+ // 2. 先停止 PLC 轮询(停止 PLC 连接尝试,避免 Quartz Job 卡住)
|
|
|
+ try
|
|
|
+ {
|
|
|
+ PlcPollingService.Instance.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] PlcPollingService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] PlcPollingService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 停止报警服务
|
|
|
+ try
|
|
|
+ {
|
|
|
+ AlarmService.Instance.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] AlarmService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] AlarmService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 停止 WebSocket 通信
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _hubClient?.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] HubClient 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] HubClient 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
_hubClient = null;
|
|
|
- _hubServer?.Dispose();
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _hubServer?.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] HubServer 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] HubServer 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
_hubServer = null;
|
|
|
- _dataLogger?.Dispose();
|
|
|
+
|
|
|
+ // 5. 停止数据日志
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _dataLogger?.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] DataLoggingService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] DataLoggingService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
_dataLogger = null;
|
|
|
|
|
|
- // 停止新集成的服务
|
|
|
+ // 6. 停止 Quartz 调度器(此时 PlcPollingJob 不会再有 PLC 连接操作)
|
|
|
try
|
|
|
{
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] 正在停止 QuartzSchedulerService...", sw.ElapsedMilliseconds);
|
|
|
QuartzSchedulerService.Instance.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] QuartzSchedulerService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] QuartzSchedulerService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 停止其他服务
|
|
|
+ try
|
|
|
+ {
|
|
|
WorkflowService.Instance.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] WorkflowService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] WorkflowService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
DeviceStateMachineManager.Instance.Clear();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] DeviceStateMachineManager 已清理", sw.ElapsedMilliseconds);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- Serilog.Log.Warning(ex, "停止新服务时出现异常");
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] DeviceStateMachineManager 清理失败", sw.ElapsedMilliseconds);
|
|
|
}
|
|
|
|
|
|
+ try
|
|
|
+ {
|
|
|
+ NotificationService.Instance.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] NotificationService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] NotificationService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 8. 重置单例(为登出/重登录准备)
|
|
|
QuartzSchedulerService.ResetInstance();
|
|
|
WorkflowService.ResetInstance();
|
|
|
-
|
|
|
+ WatchdogService.ResetInstance();
|
|
|
AlarmService.ResetInstance();
|
|
|
PlcPollingService.ResetInstance();
|
|
|
- PlcService.Dispose();
|
|
|
+
|
|
|
+ // 9. 停止 PLC 底层连接
|
|
|
+ try
|
|
|
+ {
|
|
|
+ PlcService.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] PlcService 已停止", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] PlcService 停止失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ sw.Stop();
|
|
|
+ Serilog.Log.Information("=== StopServices 完成 (耗时 {Elapsed}ms) ===", sw.ElapsedMilliseconds);
|
|
|
}
|
|
|
|
|
|
private void Cleanup()
|
|
|
{
|
|
|
+ Serilog.Log.Information("========== Cleanup 开始 ==========");
|
|
|
+ var sw = System.Diagnostics.Stopwatch.StartNew();
|
|
|
+
|
|
|
if (Interlocked.Exchange(ref _cleanupStarted, 1) != 0)
|
|
|
+ {
|
|
|
+ Serilog.Log.Information("Cleanup 已在进行中,跳过重复调用");
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
StopServices();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] StopServices 已完成", sw.ElapsedMilliseconds);
|
|
|
+
|
|
|
if (_userLoggedOutHandler != null)
|
|
|
{
|
|
|
AuthService.UserLoggedOut -= _userLoggedOutHandler;
|
|
|
_userLoggedOutHandler = null;
|
|
|
}
|
|
|
ThemeService.Instance.ThemeChanged -= ApplyTheme;
|
|
|
- SingleInstanceHelper.Release();
|
|
|
- DatabaseService.Dispose();
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ SingleInstanceHelper.Release();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] SingleInstanceHelper 已释放", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] SingleInstanceHelper 释放失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ DatabaseService.Dispose();
|
|
|
+ Serilog.Log.Information("[{Elapsed}ms] DatabaseService 已释放", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Serilog.Log.Warning(ex, "[{Elapsed}ms] DatabaseService 释放失败", sw.ElapsedMilliseconds);
|
|
|
+ }
|
|
|
+
|
|
|
+ sw.Stop();
|
|
|
+ Serilog.Log.Information("========== Cleanup 完成 (总耗时 {Elapsed}ms) ==========", sw.ElapsedMilliseconds);
|
|
|
+
|
|
|
+ // 最后关闭日志(确保前面的日志都写入)
|
|
|
LogService.Shutdown();
|
|
|
}
|
|
|
|