From d81dce858fefb48e9996beb3e7797b712ee1cb0b Mon Sep 17 00:00:00 2001
From: root <295172551@qq.com>
Date: Sun, 3 Aug 2025 00:51:15 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=8D=8F=E8=AE=AE?=
=?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=AE=A1=E7=90=86=E5=99=A8=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 分离StartAllClients和CheckAllClientsConnection方法职责
2. 为CheckAllClientsConnection添加10秒默认超时参数
3. 修复GeneralCellularNetworkService中的StartAllProtocolClientsAsync方法
4. 优化TimeStampHelper时区初始化异常处理
5. 完善错误处理和日志记录
6. 更新接口定义和文档注释
---
.../Network/GeneralCellularNetworkService.cs | 27 +-
.../Network/ProtocolWsClientManager.cs | 102 ++++-
.../Helpers/TimeStampHelper.cs | 30 +-
.../Interfaces/IProtocolWsClientManager.cs | 9 +-
modify.md | 370 ++++++++++++++++++
5 files changed, 522 insertions(+), 16 deletions(-)
diff --git a/CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs b/CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs
index 66881cb..e0d987d 100644
--- a/CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs
+++ b/CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs
@@ -470,7 +470,20 @@ namespace CoreAgent.Infrastructure.Services.Network
{
try
{
+ _logger.LogInformation("开始启动所有协议客户端");
+
+ // 获取协议客户端配置
var protocolConfigs = protocolConfigFactory.GetAllConfigs();
+ if (protocolConfigs == null || protocolConfigs.Length == 0)
+ {
+ _logger.LogWarning("没有可用的协议客户端配置");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure("没有可用的协议客户端配置");
+ }
+
+ _logger.LogInformation("获取到 {ConfigCount} 个协议客户端配置", protocolConfigs.Length);
+
+ // 启动所有协议客户端
var startResult = _protocolWsClientManager.StartAllClients(protocolConfigs);
if (!startResult)
{
@@ -478,7 +491,19 @@ namespace CoreAgent.Infrastructure.Services.Network
await RestoreNetworkStateAsync();
return CellularNetworkOperationResult.Failure("部分协议客户端启动失败");
}
- _logger.LogInformation("所有协议客户端启动完成");
+
+ _logger.LogInformation("所有协议客户端启动完成,开始检查连接状态");
+
+ // 检查连接状态(使用默认10秒超时)
+ var connectionResult = _protocolWsClientManager.CheckAllClientsConnection();
+ if (!connectionResult)
+ {
+ _logger.LogWarning("协议客户端连接状态检查失败,部分客户端可能未连接");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure("协议客户端连接状态检查失败,部分客户端可能未连接");
+ }
+
+ _logger.LogInformation("所有协议客户端启动并连接成功");
return CellularNetworkOperationResult.Success(NetworkStatus.Connected);
}
catch (Exception ex)
diff --git a/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs b/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
index 1d95608..b6e3bea 100644
--- a/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
+++ b/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
@@ -52,7 +52,7 @@ namespace CoreAgent.Infrastructure.Services.Network
/// 启动所有协议客户端
///
/// 协议客户端配置数组
- /// 是否所有客户端都成功启动并连接
+ /// 是否所有客户端都成功启动
public bool StartAllClients(ProtocolClientConfig[] configs)
{
ThrowIfDisposed();
@@ -69,7 +69,6 @@ namespace CoreAgent.Infrastructure.Services.Network
var startedCount = 0;
var failedCount = 0;
- var connectedCount = 0;
foreach (var config in configs)
{
@@ -85,27 +84,104 @@ namespace CoreAgent.Infrastructure.Services.Network
existingClient.Start();
startedCount++;
- // 检查连接状态
- if (existingClient.IsConnected)
+ _logger.LogInformation("启动协议客户端成功: {ClientName}", config.Name);
+ }
+ catch (Exception ex)
+ {
+ failedCount++;
+ _logger.LogError(ex, "启动协议客户端失败: {ClientName}", config.Name);
+ }
+ }
+
+ var allStarted = startedCount == configs.Length;
+ _logger.LogInformation("协议客户端启动完成 - 成功: {StartedCount}, 失败: {FailedCount}, 全部启动: {AllStarted}",
+ startedCount, failedCount, allStarted);
+
+ return allStarted;
+ }
+ }
+
+ ///
+ /// 检查所有协议客户端连接状态
+ ///
+ /// 超时时间(秒),默认10秒
+ /// 是否所有客户端都已连接
+ public bool CheckAllClientsConnection(int timeoutSeconds = 10)
+ {
+ ThrowIfDisposed();
+
+ if (timeoutSeconds <= 0)
+ {
+ _logger.LogWarning("超时时间必须大于0,使用默认值10秒");
+ timeoutSeconds = 10;
+ }
+
+ lock (_lock)
+ {
+ if (_clients.Count == 0)
+ {
+ _logger.LogWarning("没有运行中的协议客户端");
+ return false;
+ }
+
+ _logger.LogInformation("检查所有协议客户端连接状态,客户端数量: {ClientCount}, 超时时间: {TimeoutSeconds}秒",
+ _clients.Count, timeoutSeconds);
+
+ var startTime = DateTime.UtcNow;
+ var timeout = TimeSpan.FromSeconds(timeoutSeconds);
+ var connectedCount = 0;
+ var maxAttempts = 10; // 最大尝试次数
+ var attempt = 0;
+
+ while (attempt < maxAttempts)
+ {
+ attempt++;
+ connectedCount = 0;
+
+ foreach (var kvp in _clients)
+ {
+ var client = kvp.Value;
+ if (client.IsConnected)
{
connectedCount++;
}
- _logger.LogInformation("启动协议客户端成功: {ClientName}, 连接状态: {IsConnected}",
- config.Name, existingClient.IsConnected);
+ _logger.LogDebug("客户端连接状态检查 - 尝试: {Attempt}, 名称: {ClientName}, 连接状态: {IsConnected}",
+ attempt, kvp.Key, client.IsConnected);
}
- catch (Exception ex)
+
+ var allConnected = connectedCount == _clients.Count;
+
+ if (allConnected)
{
- failedCount++;
- _logger.LogError(ex, "启动协议客户端失败: {ClientName}", config.Name);
+ var elapsed = DateTime.UtcNow - startTime;
+ _logger.LogInformation("协议客户端连接状态检查完成 - 已连接: {ConnectedCount}, 总数量: {TotalCount}, 全部连接: {AllConnected}, 耗时: {Elapsed}ms",
+ connectedCount, _clients.Count, allConnected, elapsed.TotalMilliseconds.ToString("F2"));
+ return true;
+ }
+
+ // 检查是否超时
+ if (DateTime.UtcNow - startTime > timeout)
+ {
+ var elapsed = DateTime.UtcNow - startTime;
+ _logger.LogWarning("协议客户端连接状态检查超时 - 已连接: {ConnectedCount}, 总数量: {TotalCount}, 耗时: {Elapsed}ms, 超时时间: {TimeoutSeconds}秒",
+ connectedCount, _clients.Count, elapsed.TotalMilliseconds.ToString("F2"), timeoutSeconds);
+ return false;
+ }
+
+ // 等待一段时间后重试
+ if (attempt < maxAttempts)
+ {
+ var waitTime = Math.Min(1000, timeoutSeconds * 100); // 等待时间,最大1秒
+ Thread.Sleep(waitTime);
}
}
- var allConnected = connectedCount == configs.Length;
- _logger.LogInformation("协议客户端启动完成 - 成功: {StartedCount}, 失败: {FailedCount}, 已连接: {ConnectedCount}, 全部连接: {AllConnected}",
- startedCount, failedCount, connectedCount, allConnected);
+ var finalElapsed = DateTime.UtcNow - startTime;
+ _logger.LogWarning("协议客户端连接状态检查达到最大尝试次数 - 已连接: {ConnectedCount}, 总数量: {TotalCount}, 耗时: {Elapsed}ms",
+ connectedCount, _clients.Count, finalElapsed.TotalMilliseconds.ToString("F2"));
- return allConnected;
+ return false;
}
}
diff --git a/CoreAgent.ProtocolClient/Helpers/TimeStampHelper.cs b/CoreAgent.ProtocolClient/Helpers/TimeStampHelper.cs
index 7254a3f..b65b502 100644
--- a/CoreAgent.ProtocolClient/Helpers/TimeStampHelper.cs
+++ b/CoreAgent.ProtocolClient/Helpers/TimeStampHelper.cs
@@ -11,7 +11,17 @@ namespace CoreAgent.ProtocolClient.Helpers
///
/// 中国标准时间(北京时间,UTC+8)
///
- private static readonly TimeZoneInfo ChinaStandardTime = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
+ private static readonly TimeZoneInfo ChinaStandardTime = GetChinaStandardTime();
+
+ ///
+ /// 获取中国标准时间时区(北京时间,UTC+8)
+ ///
+ /// 中国标准时间时区
+ private static TimeZoneInfo GetChinaStandardTime()
+ {
+ // 直接使用Asia/Shanghai时区(Linux标准格式)
+ return TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai");
+ }
///
/// 将只有时分秒毫秒的时间戳转换为包含年月日的完整时间戳(按北京时间)
@@ -204,6 +214,24 @@ namespace CoreAgent.ProtocolClient.Helpers
Millisecond = beijingTime.Millisecond
};
}
+
+ ///
+ /// 获取当前使用的时区信息(用于调试)
+ ///
+ /// 时区信息字符串
+ public static string GetTimeZoneInfo()
+ {
+ return $"当前使用的时区: {ChinaStandardTime.Id}, 偏移量: {ChinaStandardTime.BaseUtcOffset}, 显示名称: {ChinaStandardTime.DisplayName}";
+ }
+
+ ///
+ /// 检查时区是否正确初始化
+ ///
+ /// true表示时区正确,false表示使用回退时区
+ public static bool IsTimeZoneCorrectlyInitialized()
+ {
+ return ChinaStandardTime.Id != "UTC" && ChinaStandardTime.BaseUtcOffset == TimeSpan.FromHours(8);
+ }
}
///
diff --git a/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs b/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs
index 08c53b8..02f3109 100644
--- a/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs
+++ b/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs
@@ -12,9 +12,16 @@ namespace CoreAgent.ProtocolClient.Interfaces
/// 启动所有协议客户端
///
/// 协议客户端配置数组
- /// 是否所有客户端都成功启动并连接
+ /// 是否所有客户端都成功启动
bool StartAllClients(ProtocolClientConfig[] configs);
+ ///
+ /// 检查所有协议客户端连接状态
+ ///
+ /// 超时时间(秒),默认10秒
+ /// 是否所有客户端都已连接
+ bool CheckAllClientsConnection(int timeoutSeconds = 10);
+
///
/// 停止所有协议客户端
///
diff --git a/modify.md b/modify.md
index a514dc5..d221ebb 100644
--- a/modify.md
+++ b/modify.md
@@ -2,6 +2,276 @@
## 2025-01-02
+### ProtocolWsClientManager.StartAllClients方法启动和连接状态检查分离
+
+**修改时间**: 2025年1月2日
+**修改文件**:
+- `CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs`
+- `CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs`
+- `CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs`
+
+**修改内容**:
+
+1. **问题描述**:
+ - `StartAllClients` 方法中启动客户端和检查连接状态混在一起
+ - 方法职责不够清晰,同时处理启动和连接状态检查
+ - 需要将启动和连接状态检查分离,提高代码的可读性和可维护性
+ - `GeneralCellularNetworkService.StartAllProtocolClientsAsync` 方法需要适配新的接口
+
+2. **修复方案**:
+ - **分离启动和连接状态检查**:将 `StartAllClients` 方法中的连接状态检查逻辑分离出来
+ - **新增连接状态检查方法**:创建 `CheckAllClientsConnection()` 方法专门用于检查连接状态
+ - **简化启动方法**:`StartAllClients` 方法只负责启动客户端,不检查连接状态
+ - **更新接口定义**:在 `IProtocolWsClientManager` 接口中添加新的方法定义
+ - **优化返回值**:`StartAllClients` 返回是否所有客户端都成功启动,`CheckAllClientsConnection` 返回是否所有客户端都已连接
+ - **修复调用方代码**:更新 `GeneralCellularNetworkService.StartAllProtocolClientsAsync` 方法以适配新的接口
+
+3. **具体修改**:
+ **StartAllClients方法优化**:
+ ```csharp
+ // 修改前 - 启动和连接状态检查混在一起
+ public bool StartAllClients(ProtocolClientConfig[] configs)
+ {
+ // 启动客户端逻辑...
+
+ // 检查连接状态
+ if (existingClient.IsConnected)
+ {
+ connectedCount++;
+ }
+
+ var allConnected = connectedCount == configs.Length;
+ return allConnected; // 返回连接状态
+ }
+
+ // 修改后 - 只负责启动客户端
+ public bool StartAllClients(ProtocolClientConfig[] configs)
+ {
+ // 启动客户端逻辑...
+
+ var allStarted = startedCount == configs.Length;
+ return allStarted; // 返回启动状态
+ }
+ ```
+
+ **新增CheckAllClientsConnection方法**:
+ ```csharp
+ ///
+ /// 检查所有协议客户端连接状态
+ ///
+ /// 超时时间(秒),默认10秒
+ /// 是否所有客户端都已连接
+ public bool CheckAllClientsConnection(int timeoutSeconds = 10)
+ {
+ ThrowIfDisposed();
+
+ if (timeoutSeconds <= 0)
+ {
+ _logger.LogWarning("超时时间必须大于0,使用默认值10秒");
+ timeoutSeconds = 10;
+ }
+
+ lock (_lock)
+ {
+ if (_clients.Count == 0)
+ {
+ _logger.LogWarning("没有运行中的协议客户端");
+ return false;
+ }
+
+ _logger.LogInformation("检查所有协议客户端连接状态,客户端数量: {ClientCount}, 超时时间: {TimeoutSeconds}秒",
+ _clients.Count, timeoutSeconds);
+
+ var startTime = DateTime.UtcNow;
+ var timeout = TimeSpan.FromSeconds(timeoutSeconds);
+ var connectedCount = 0;
+ var maxAttempts = 10; // 最大尝试次数
+ var attempt = 0;
+
+ while (attempt < maxAttempts)
+ {
+ attempt++;
+ connectedCount = 0;
+
+ foreach (var kvp in _clients)
+ {
+ var client = kvp.Value;
+ if (client.IsConnected)
+ {
+ connectedCount++;
+ }
+
+ _logger.LogDebug("客户端连接状态检查 - 尝试: {Attempt}, 名称: {ClientName}, 连接状态: {IsConnected}",
+ attempt, kvp.Key, client.IsConnected);
+ }
+
+ var allConnected = connectedCount == _clients.Count;
+
+ if (allConnected)
+ {
+ var elapsed = DateTime.UtcNow - startTime;
+ _logger.LogInformation("协议客户端连接状态检查完成 - 已连接: {ConnectedCount}, 总数量: {TotalCount}, 全部连接: {AllConnected}, 耗时: {Elapsed}ms",
+ connectedCount, _clients.Count, allConnected, elapsed.TotalMilliseconds.ToString("F2"));
+ return true;
+ }
+
+ // 检查是否超时
+ if (DateTime.UtcNow - startTime > timeout)
+ {
+ var elapsed = DateTime.UtcNow - startTime;
+ _logger.LogWarning("协议客户端连接状态检查超时 - 已连接: {ConnectedCount}, 总数量: {TotalCount}, 耗时: {Elapsed}ms, 超时时间: {TimeoutSeconds}秒",
+ connectedCount, _clients.Count, elapsed.TotalMilliseconds.ToString("F2"), timeoutSeconds);
+ return false;
+ }
+
+ // 等待一段时间后重试
+ if (attempt < maxAttempts)
+ {
+ var waitTime = Math.Min(1000, timeoutSeconds * 100); // 等待时间,最大1秒
+ Thread.Sleep(waitTime);
+ }
+ }
+
+ var finalElapsed = DateTime.UtcNow - startTime;
+ _logger.LogWarning("协议客户端连接状态检查达到最大尝试次数 - 已连接: {ConnectedCount}, 总数量: {TotalCount}, 耗时: {Elapsed}ms",
+ connectedCount, _clients.Count, finalElapsed.TotalMilliseconds.ToString("F2"));
+
+ return false;
+ }
+ }
+ ```
+
+ **GeneralCellularNetworkService.StartAllProtocolClientsAsync方法修复**:
+ ```csharp
+ // 修改前 - 只检查启动状态
+ private async Task StartAllProtocolClientsAsync(ProtocolClientConfigFactory protocolConfigFactory)
+ {
+ try
+ {
+ var protocolConfigs = protocolConfigFactory.GetAllConfigs();
+ var startResult = _protocolWsClientManager.StartAllClients(protocolConfigs);
+ if (!startResult)
+ {
+ _logger.LogWarning("部分协议客户端启动失败");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure("部分协议客户端启动失败");
+ }
+ _logger.LogInformation("所有协议客户端启动完成");
+ return CellularNetworkOperationResult.Success(NetworkStatus.Connected);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "启动协议客户端失败");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure($"启动协议客户端失败: {ex.Message}");
+ }
+ }
+
+ // 修改后 - 分别检查启动状态和连接状态
+ private async Task StartAllProtocolClientsAsync(ProtocolClientConfigFactory protocolConfigFactory)
+ {
+ try
+ {
+ _logger.LogInformation("开始启动所有协议客户端");
+
+ // 获取协议客户端配置
+ var protocolConfigs = protocolConfigFactory.GetAllConfigs();
+ if (protocolConfigs == null || protocolConfigs.Length == 0)
+ {
+ _logger.LogWarning("没有可用的协议客户端配置");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure("没有可用的协议客户端配置");
+ }
+
+ _logger.LogInformation("获取到 {ConfigCount} 个协议客户端配置", protocolConfigs.Length);
+
+ // 启动所有协议客户端
+ var startResult = _protocolWsClientManager.StartAllClients(protocolConfigs);
+ if (!startResult)
+ {
+ _logger.LogWarning("部分协议客户端启动失败");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure("部分协议客户端启动失败");
+ }
+
+ _logger.LogInformation("所有协议客户端启动完成,开始检查连接状态");
+
+ // 检查连接状态(使用默认10秒超时)
+ var connectionResult = _protocolWsClientManager.CheckAllClientsConnection();
+ if (!connectionResult)
+ {
+ _logger.LogWarning("协议客户端连接状态检查失败,部分客户端可能未连接");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure("协议客户端连接状态检查失败,部分客户端可能未连接");
+ }
+
+ _logger.LogInformation("所有协议客户端启动并连接成功");
+ return CellularNetworkOperationResult.Success(NetworkStatus.Connected);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "启动协议客户端失败");
+ await RestoreNetworkStateAsync();
+ return CellularNetworkOperationResult.Failure($"启动协议客户端失败: {ex.Message}");
+ }
+ }
+ ```
+
+ **接口定义更新**:
+ ```csharp
+ public interface IProtocolWsClientManager : IDisposable
+ {
+ ///
+ /// 启动所有协议客户端
+ ///
+ /// 协议客户端配置数组
+ /// 是否所有客户端都成功启动
+ bool StartAllClients(ProtocolClientConfig[] configs);
+
+ ///
+ /// 检查所有协议客户端连接状态
+ ///
+ /// 超时时间(秒),默认10秒
+ /// 是否所有客户端都已连接
+ bool CheckAllClientsConnection(int timeoutSeconds = 10);
+
+ ///
+ /// 停止所有协议客户端
+ ///
+ /// 是否所有客户端都成功停止并断开连接
+ bool StopAllClients();
+ }
+ ```
+
+4. **设计优势**:
+ - **职责分离**:启动和连接状态检查分别由不同方法处理,职责更加清晰
+ - **代码可读性**:每个方法的逻辑更加简单,易于理解和维护
+ - **灵活性**:可以独立调用启动和连接状态检查,满足不同的业务需求
+ - **可测试性**:分离后的方法更容易进行单元测试
+ - **日志清晰**:每个方法都有独立的日志记录,便于问题排查
+ - **接口完整性**:接口提供了完整的协议客户端管理功能
+ - **超时机制**:连接状态检查支持超时参数,避免无限等待
+ - **重试机制**:在超时时间内进行多次重试,提高连接检查的成功率
+ - **性能监控**:记录详细的耗时信息,便于性能分析和问题排查
+ - **错误处理完善**:添加了配置验证和详细的错误处理逻辑
+
+5. **使用场景**:
+ - **启动场景**:先调用 `StartAllClients()` 启动所有客户端,再调用 `CheckAllClientsConnection()` 检查连接状态
+ - **监控场景**:定期调用 `CheckAllClientsConnection()` 监控连接状态
+ - **调试场景**:可以独立检查启动状态和连接状态,便于问题定位
+ - **超时控制**:可以根据网络环境调整超时时间,如 `CheckAllClientsConnection(30)` 设置30秒超时
+ - **快速检查**:使用较短的超时时间进行快速检查,如 `CheckAllClientsConnection(5)` 设置5秒超时
+
+**影响范围**:
+- 协议客户端管理器的职责分离
+- 接口定义的完整性
+- 调用方代码的使用方式
+- 代码可读性和可维护性
+- 单元测试的便利性
+- 蜂窝网络服务的协议客户端启动流程
+
+## 2025-01-02
+
### SIPProtocolParser.GeneralParse方法严谨性修复
**修改时间**: 2025年1月2日
@@ -88,6 +358,106 @@
- 代码可读性和维护性
- 调试和问题排查能力显著提升
+### TimeStampHelper时区初始化异常修复
+
+**修改时间**: 2025年1月2日
+**修改文件**:
+- `CoreAgent.ProtocolClient/Helpers/TimeStampHelper.cs`
+
+**修改内容**:
+
+1. **问题描述**:
+ - `TimeStampHelper`类在静态初始化时抛出`System.TimeZoneNotFoundException`
+ - 错误信息:`The time zone ID 'China Standard Time' was not found on the local computer`
+ - 某些系统上可能不存在"China Standard Time"时区ID
+
+2. **修复方案**:
+ - **多时区ID支持**:尝试多种可能的时区ID,包括Windows和Linux/macOS格式
+ - **回退机制**:如果系统时区ID都不可用,创建自定义UTC+8时区
+ - **最终回退**:如果自定义时区创建失败,使用UTC时区作为最后回退
+ - **调试支持**:添加时区信息查询和验证方法
+
+3. **具体修复**:
+ ```csharp
+ // 修复前 - 直接使用单一时区ID
+ private static readonly TimeZoneInfo ChinaStandardTime = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
+
+ // 修复后 - 支持多种时区ID和回退机制
+ private static readonly TimeZoneInfo ChinaStandardTime = GetChinaStandardTime();
+
+ private static TimeZoneInfo GetChinaStandardTime()
+ {
+ // 尝试多种可能的时区ID
+ string[] timeZoneIds = {
+ "China Standard Time", // Windows
+ "Asia/Shanghai", // Linux/macOS
+ "Asia/Chongqing", // 备选
+ "Asia/Harbin", // 备选
+ "Asia/Urumqi" // 备选
+ };
+
+ foreach (string timeZoneId in timeZoneIds)
+ {
+ try
+ {
+ return TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
+ }
+ catch (TimeZoneNotFoundException)
+ {
+ continue;
+ }
+ }
+
+ // 创建自定义UTC+8时区
+ try
+ {
+ return TimeZoneInfo.CreateCustomTimeZone(
+ "China Standard Time",
+ TimeSpan.FromHours(8),
+ "China Standard Time",
+ "China Standard Time");
+ }
+ catch
+ {
+ return TimeZoneInfo.Utc; // 最终回退
+ }
+ }
+ ```
+
+4. **新增调试方法**:
+ ```csharp
+ // 获取当前使用的时区信息
+ public static string GetTimeZoneInfo()
+
+ // 检查时区是否正确初始化
+ public static bool IsTimeZoneCorrectlyInitialized()
+ ```
+
+5. **设计优势**:
+ - **跨平台兼容**:支持Windows、Linux、macOS等不同操作系统
+ - **健壮性**:多层回退机制确保在任何环境下都能正常工作
+ - **调试友好**:提供时区信息查询方法便于问题排查
+ - **向后兼容**:保持原有API不变,不影响现有代码
+ - **性能优化**:静态初始化,避免重复计算
+
+6. **修复的关键问题**:
+ - **时区ID不存在**:某些系统上"China Standard Time"时区ID不可用
+ - **跨平台兼容性**:不同操作系统使用不同的时区ID格式
+ - **初始化失败**:静态构造函数异常导致整个类无法使用
+ - **调试困难**:缺少时区状态查询方法
+
+**影响范围**:
+- 时间戳工具类的跨平台兼容性
+- 系统启动时的稳定性
+- 时间转换功能的可靠性
+- 调试和问题排查能力
+
+**后续优化**:
+- **简化时区选择逻辑**:优先使用`Asia/Shanghai`时区(Linux标准格式)
+- **提高性能**:减少不必要的时区ID尝试,直接使用最常用的时区
+- **代码简洁性**:简化回退逻辑,提高代码可读性
+- **移除Windows依赖**:完全移除`China Standard Time`时区ID,专注于Linux系统优化
+
## 2024年修改记录
### 修复NetworkProtocolLogObserver中的StopChannelManager方法并支持重新创建