csredis icon indicating copy to clipboard operation
csredis copied to clipboard

[Redis] Lock 严重 BUG

Open trueai-org opened this issue 4 weeks ago • 1 comments

版本:>= 3.8.806 都将会出现此 BUG。

当 redis.Lock(lockKey, 10) 设置时间 > 程序执行时间时,系统就会崩溃。

using CSRedis;

namespace redeisqueuetest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            // 1. 初始化 Redis
            var redis = new CSRedisClient("***,password=***,defaultDatabase=0,poolsize=50");
            RedisHelper.Initialization(redis);

            var lockKey = "my_distributed_lock";

            var task1 = new Task(() =>
            {
                var v = AcquireLockExample(redis, lockKey, "Task 1");

                Console.WriteLine("task1: " + v);
            });
            var task2 = new Task(() =>
            {
                var v = AcquireLockExample(redis, lockKey, "Task 2");

                Console.WriteLine("task2: " + v);
            });
            task1.Start();
            task2.Start();

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        private static bool AcquireLockExample(CSRedisClient redis, string lockKey, string v)
        {
            try
            {
                using var run = redis.Lock(lockKey, 10);
                {
                    if (run != null)
                    {
                        Console.WriteLine($"{v} 获取到锁并执行");

                        // 模拟任务执行
                        Thread.Sleep(5000);

                        return true;
                    }
                    else
                    {
                        Console.WriteLine($"{v} 获取锁失败");

                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}
System.ObjectDisposedException
  HResult=0x80131622
  Message=The CancellationTokenSource has been disposed.
  Source=System.Private.CoreLib
  StackTrace:
   在 System.ThrowHelper.ThrowObjectDisposedException(ExceptionResource resource) 在 System\ThrowHelper.cs 中: 第 366 行
   在 System.Threading.CancellationTokenSource.Cancel() 在 System.Threading\CancellationTokenSource.cs 中: 第 368 行
   在 CSRedis.CSRedisClientLock.Refresh(Int32 milliseconds)
   在 CSRedis.CSRedisClientLock.<>c__DisplayClass6_0.<.ctor>b__0(Object state2)
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading\ExecutionContext.cs 中: 第 138 行
--- 上一位置中堆栈跟踪的末尾 ---
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading\ExecutionContext.cs 中: 第 153 行
   在 System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool) 在 System.Threading\TimerQueueTimer.cs 中: 第 259 行
   在 System.Threading.TimerQueue.FireNextTimers() 在 System.Threading\TimerQueue.cs 中: 第 218 行
   在 System.Threading.ThreadPoolWorkQueue.Dispatch() 在 System.Threading\ThreadPoolWorkQueue.cs 中: 第 740 行
   在 System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() 在 System.Threading\PortableThreadPool.cs 中: 第 1338 行

trueai-org avatar Nov 26 '25 02:11 trueai-org

类似的代码: using var run = redis.Lock(lockKey, 10); { if (run != null) { Console.WriteLine($"{v} 获取到锁并执行");

                    // 模拟任务执行
                    Thread.Sleep(5000);

                    return true;
                }
                else
                {
                    Console.WriteLine($"{v} 获取锁失败");

                    return false;
                }
            }

并发锁根本没用,并发会重复获取锁,还是别用!

vipxiaoma avatar Dec 05 '25 06:12 vipxiaoma