wanshenmean
3 天以前 b690250002ee04f4309e6a90fd16fbfd9bd959e2
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using Newtonsoft.Json;
using WIDESEAWCS_Core.LogHelper;
using Serilog;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_Model.Models;
@@ -12,6 +12,7 @@
    /// <remarks>
    /// 核心功能是通过 IRobotStateRepository 管理数据库中的机械手状态。
    /// 提供乐观并发控制,通过 Version 字段防止并发更新时的数据覆盖问题。
    /// 同时提供基于 SemaphoreSlim 的互斥锁,确保消息处理与 Job 执行不会并发操作同一设备状态。
    /// </remarks>
    public class RobotStateManager
    {
@@ -26,6 +27,15 @@
        private readonly ILogger _logger;
        /// <summary>
        /// 每个设备的异步互斥锁字典,用于 Job 执行与消息处理之间的互斥
        /// </summary>
        /// <remarks>
        /// Key 为设备 IP 地址,Value 为该设备专属的 SemaphoreSlim(1,1)。
        /// 确保同一设备的 Job 轮询和 TCP 消息处理不会同时操作状态。
        /// </remarks>
        private readonly ConcurrentDictionary<string, SemaphoreSlim> _robotLocks = new();
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="repository">仓储服务实例</param>
@@ -34,6 +44,20 @@
        {
            _repository = repository;
            _logger = logger;
        }
        /// <summary>
        /// 获取或创建指定设备的异步互斥锁
        /// </summary>
        /// <remarks>
        /// 使用 ConcurrentDictionary 确保每个设备 IP 对应唯一的 SemaphoreSlim(1,1)。
        /// 该锁用于 Job 执行与 TCP 消息处理之间的互斥,防止并发操作同一设备状态。
        /// </remarks>
        /// <param name="ipAddress">设备 IP 地址</param>
        /// <returns>该设备的信号量实例</returns>
        public SemaphoreSlim GetOrCreateLock(string ipAddress)
        {
            return _robotLocks.GetOrAdd(ipAddress, _ => new SemaphoreSlim(1, 1));
        }
        /// <summary>
@@ -94,8 +118,7 @@
            if (currentEntity == null)
            {
                _repository.GetOrCreate(newState.IPAddress, newState.RobotCrane ?? new RobotCraneDevice());
                _logger.LogDebug("TryUpdateStateSafely:创建新状态,IP: {IpAddress}", ipAddress);
                QuartzLogger.Debug($"创建新状态,IP: {ipAddress}", ipAddress);
                QuartzLogHelper.LogDebug(_logger, $"创建新状态,IP: {ipAddress}", ipAddress);
                return true;
            }
@@ -112,8 +135,7 @@
            if (!success)
            {
                _logger.LogWarning("TryUpdateStateSafely:版本冲突,更新失败,IP: {IpAddress},期望版本: {ExpectedVersion}", ipAddress, expectedVersion);
                QuartzLogger.Warn($"版本冲突,更新失败,IP: {ipAddress}", ipAddress);
                QuartzLogHelper.LogWarn(_logger, $"TryUpdateStateSafely:版本冲突,更新失败,IP: {ipAddress},期望版本: {expectedVersion}", ipAddress);
            }
            return success;
@@ -161,4 +183,4 @@
            return _repository.ToSocketState(entity);
        }
    }
}
}