设备数量不对等适配

This commit is contained in:
hsc
2026-06-22 17:22:21 +08:00
parent cba9af2892
commit 1faae12822
2 changed files with 55 additions and 8 deletions

View File

@@ -19,6 +19,7 @@ namespace UIShare.GlobalVariable
{
private object _lockObj = new object();
public SystemConfig _systemConfig { get; set; }
private readonly GlobalInfo _globalInfo;
/// <summary>按 DeviceName 索引的设备字典,便于业务层按名取实例。</summary>
public IDictionary<string, IBaseInterface> DeviceMap { get; private set; }
@@ -27,11 +28,33 @@ namespace UIShare.GlobalVariable
/// <summary>类名 → Type 的反射缓存(仅扫描一次)。</summary>
private static readonly IReadOnlyDictionary<string, Type> _deviceTypeMap = BuildDeviceTypeMap();
public DeviceManager(SystemConfig systemConfig)
public DeviceManager(SystemConfig systemConfig, GlobalInfo globalInfo)
{
_systemConfig = systemConfig;
_globalInfo = globalInfo;
InitDevices();
}
/// <summary>
/// 根据设备配置提取唯一的硬件指纹字符串。
/// <para>Tcp → "Tcp:IP:Port"Serial → "Serial:PortName";无法识别则返回空字符串。</para>
/// </summary>
private static string ExtractHardwareFingerprint(DeviceInfoVM config)
{
if (string.Equals(config.ConnectionType, "Tcp", StringComparison.OrdinalIgnoreCase)
&& config.TcpConfig != null)
{
return $"Tcp:{config.TcpConfig.IPAddress}:{config.TcpConfig.Port}";
}
if (string.Equals(config.ConnectionType, "Serial", StringComparison.OrdinalIgnoreCase)
&& config.SerialPortConfig != null)
{
return $"Serial:{config.SerialPortConfig.PortName}";
}
return string.Empty;
}
private void InitDevices()
{
DeviceMap = new Dictionary<string, IBaseInterface>(StringComparer.OrdinalIgnoreCase);
@@ -51,24 +74,41 @@ namespace UIShare.GlobalVariable
try
{
IBaseInterface? instance = config.ConnectionType switch
// 第一步:提取硬件指纹,为空则跳过
var fingerprint = ExtractHardwareFingerprint(config);
if (string.IsNullOrEmpty(fingerprint))
{
"Tcp" => CreateTcpDevice(deviceType, config.TcpConfig),
"Serial" => CreateSerialDevice(deviceType, config.SerialPortConfig),
_ => null
};
LoggerHelper.Warn($"设备 [{config.DeviceName}] 无法提取硬件指纹(连接方式={config.ConnectionType}),已跳过。");
continue;
}
// 第二步:原子化获取或添加 Lazy 包装盒,确保同一指纹全局只创建一个实例
var lazy = _globalInfo.HardwarePool.GetOrAdd(fingerprint, key => new Lazy<IBaseInterface>(() =>
{
return config.ConnectionType switch
{
"Tcp" => CreateTcpDevice(deviceType, config.TcpConfig)!,
"Serial" => CreateSerialDevice(deviceType, config.SerialPortConfig)!,
_ => null!
};
}));
// 第三步安全拆盒Lazy 内部线程锁保证只实例化一次
var instance = lazy.Value;
if (instance == null)
{
LoggerHelper.Warn($"设备 [{config.DeviceName}] 连接方式 [{config.ConnectionType}] 不支持,已跳过。");
continue;
}
// 第四步:绑定逻辑名 → 同一物理设备可被多个台架名称映射
if (!string.IsNullOrWhiteSpace(config.DeviceName))
{
DeviceMap[config.DeviceName] = instance;
}
LoggerHelper.Info($"已加载设备 [{config.DeviceName} / {config.DeviceType} / {config.ConnectionType}]");
LoggerHelper.Info($"已加载设备 [{config.DeviceName} / {config.DeviceType} / {config.ConnectionType}] 指纹={fingerprint}");
}
catch (Exception ex)
{