Beispiel #1
0
        public static async Task <(bool Success, string LockValue)> LockAsync(this IDatabase redisDb, string cacheKey, int timeoutSeconds = 5, bool autoDelay = true)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotLessThanOrEqualZero(timeoutSeconds, nameof(timeoutSeconds));

            var  lockKey             = GetLockKey(cacheKey);
            var  lockValue           = Guid.NewGuid().ToString();
            var  timeoutMilliseconds = timeoutSeconds * 1000;
            var  expiration          = TimeSpan.FromMilliseconds(timeoutMilliseconds);
            bool flag = await redisDb.StringSetAsync(lockKey, lockValue, expiration, When.NotExists);

            if (flag && autoDelay)
            {
                var refreshMilliseconds = (int)(timeoutMilliseconds / 2.0);
                var autoDelayTimer      = new Timer(timerState => Delay(redisDb, lockKey, lockValue, timeoutMilliseconds), null, refreshMilliseconds, refreshMilliseconds);
                var addResult           = AutoDelayTimers.Instance.TryAdd(lockKey, autoDelayTimer);
                if (!addResult)
                {
                    autoDelayTimer?.Dispose();
                    await redisDb.SafedUnLockAsync(lockKey, lockValue);

                    return(false, null);
                }
            }
            return(flag, flag ? lockValue : null);
        }