控制台例子:
1. Nuget包管理器添加 StackExchange.Redis
2.代码如下:
using StackExchange.Redis; ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost,password=123456"); IDatabase db = redis.GetDatabase(); //redis键名 string resource = "myResourceName"; //锁的令牌 string lockToken = Guid.NewGuid().ToString(); //过期时间 TimeSpan expiry = TimeSpan.FromSeconds(5); var tasks = new Task[10]; for (int i = 0; i < 10; i++) { int client = (i + 1); tasks[i] = Task.Run(async () => { while (true) { //获得锁 if (db.LockTake(resource, lockToken, expiry)) { Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} ********************************* 客户端{client} 创建了锁 ********************************* "); //开启异步线程,定时2秒延长锁 var cancellationTokenSource = new CancellationTokenSource(); var extendLockTask = Task.Run(async () => { while (true) { await Task.Delay(TimeSpan.FromSeconds(2), cancellationTokenSource.Token); bool extended = db.LockExtend(resource, lockToken, expiry); if (extended) { Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} --------------- 客户端{client} 已延长了锁 ---------------"); } else { Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")}--------------- 客户端{client} 延长了锁失败!---------------"); break; } } }, cancellationTokenSource.Token); //模拟任务耗时 await Task.Delay(60); //取消延长 cancellationTokenSource.Cancel(); try { await extendLockTask; } catch (OperationCanceledException) { //Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")}--------------- 客户端{client} 延长任务取消!---------------"); } //释放锁 db.LockRelease(resource, lockToken); Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} ********************************* 客户端{client} 释放了锁 ********************************* "); break; } else { //获取锁失败以后重试 //Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} 客户端{client}获取锁失败,正在重试..."); //await Task.Delay(50); } } }); } Task.WaitAll(tasks); Task.WaitAll(tasks); Console.WriteLine("按下回车键停止..."); Console.ReadLine();