csredis
csredis copied to clipboard
[Redis] Lock 严重 BUG
版本:>= 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 行
类似的代码: using var run = redis.Lock(lockKey, 10); { if (run != null) { Console.WriteLine($"{v} 获取到锁并执行");
// 模拟任务执行
Thread.Sleep(5000);
return true;
}
else
{
Console.WriteLine($"{v} 获取锁失败");
return false;
}
}
并发锁根本没用,并发会重复获取锁,还是别用!