using Microsoft.Extensions.Logging; namespace RedisHelper { public class DistributedLock : IDistributedLock { private readonly ICache _cache; private readonly ILogger _logger; public DistributedLock(ICache cache, ILogger logger) { _cache = cache; _logger = logger; } public async Task TryExecuteAsync(string key, Func> action, int expiry = 30, bool retry = false, int retryDelay = 100) { string lockKey = GetLockKey(key); string lockValue = Guid.NewGuid().ToString(); while (true) { if (TryAcquireLock(lockKey, lockValue, expiry)) { try { return await action(); } finally { ReleaseLock(lockKey, lockValue); } } if (!retry) { return default(T); } await Task.Delay(retryDelay); } } public async Task TryExecuteAsync(string key, Func action, int expiry = 30, bool retry = false, int retryDelay = 100) { string lockKey = GetLockKey(key); string lockValue = Guid.NewGuid().ToString(); while (true) { if (TryAcquireLock(lockKey, lockValue, expiry)) { try { await action(); return true; } finally { ReleaseLock(lockKey, lockValue); } } if (!retry) { return false; } await Task.Delay(retryDelay); } } public T TryExecute(string key, Func action, int expiry = 30, bool retry = false, int retryDelay = 100) { string lockKey = GetLockKey(key); string lockValue = Guid.NewGuid().ToString(); while (true) { if (TryAcquireLock(lockKey, lockValue, expiry)) { try { return action(); } finally { ReleaseLock(lockKey, lockValue); } } if (!retry) { return default(T); } Thread.Sleep(retryDelay); } } public bool TryExecute(string key, Action action, int expiry = 30, bool retry = false, int retryDelay = 100) { string lockKey = GetLockKey(key); string lockValue = Guid.NewGuid().ToString(); while (true) { if (TryAcquireLock(lockKey, lockValue, expiry)) { try { action(); return true; } finally { ReleaseLock(lockKey, lockValue); } } if (!retry) { return false; } Thread.Sleep(retryDelay); } } private bool TryAcquireLock(string lockKey, string lockValue, int expiry) { try { var redis = _cache.GetFullRedis(); bool acquired = redis.Add(lockKey, lockValue, expiry); if (acquired) { } return acquired; } catch (Exception ex) { _logger.LogError(ex, $"获取分布式锁时发生错�? {lockKey}"); return false; } } private void ReleaseLock(string lockKey, string lockValue) { try { var redis = _cache.GetFullRedis(); var currentValue = redis.Get(lockKey); if (currentValue == lockValue) { redis.Remove(lockKey); } } catch (Exception ex) { _logger.LogError(ex, $"释放分布式锁时发生错�? {lockKey}"); } } private string GetLockKey(string key) { return $"{key}"; } } }