/// <summary> /// 读取分布式锁 执行代码前读取锁 /// </summary> /// <param name="key">锁key</param> /// <param name="lockExpirySeconds">锁自动超时时间(秒)</param> /// <param name="waitLockSeconds">等待锁时间(秒)</param> /// <returns></returns> public static async Task <bool> TryLockAsync(string key, int lockExpirySeconds = 10, double waitLockSeconds = 0) { //间隔等待50毫秒 int waitIntervalMs = 50; string lockKey = LOCK_NAME + key; DateTime begin = DateTime.Now; while (true) { //循环获取取锁 if (await CsRedisManager.SetNxAsync(lockKey, 1)) { //设置锁的过期时间 await CsRedisManager.ExpireAsync(lockKey, lockExpirySeconds); return(true); } //不等待锁则返回 if (waitLockSeconds == 0) { break; } //超过等待时间,则不再等待 if ((DateTime.Now - begin).TotalSeconds >= waitLockSeconds) { break; } Thread.Sleep(waitIntervalMs); } return(false); }
/// <summary> /// 委托事件消费队列,(如在hash表中检查出有失败得渠道id,则消费超时) /// </summary> /// <param name="queueName">队列名</param> /// <param name="postTask">消费后执行事务</param> /// <param name="sleepTime">等待时间,单位(微秒),由PV信号量控制,建议设为1ms</param> /// <returns></returns> public static async Task <string> ConsumerAsyncDelegation(string queueName, PostConsumptionTask postTask, int sleepTime) { using (var connector = MQConnection.CreateConnection()) { if (connector.IsOpen) { using (var channel = connector.CreateModel()) { if (channel.IsOpen) { var consumer = new AsyncEventingBasicConsumer(channel); consumer.Received += async(ch, response) => { using (var redisLock = CsRedisManager.CsRedisLock(queueName, 20 * 60)) { var data = response.Body.ToArray(); var value = Encoding.UTF8.GetString(data); try { await postTask(value); channel.BasicAck(response.DeliveryTag, false); await consumer.HandleBasicCancel(response.ConsumerTag); } catch { await CsRedisManager.HSetAsync($"{MQFailureConsumptionRedisKey}{queueName}", response.DeliveryTag.ToString(), value); await consumer.HandleBasicCancel(response.ConsumerTag); } redisLock.Unlock(); } }; channel.BasicConsume(queueName, false, consumer); //PV Signaling var signal = true; while (!consumer.IsRunning && signal) { System.Threading.Thread.Sleep(sleepTime); while (consumer.IsRunning) { signal = false; } } await Task.Yield(); return("success"); } else { return(""); } } } else { return(""); } } }
/// <summary> /// 释放锁 执行代码后调用释放锁 /// </summary> /// <param name="key"></param> public static async Task UnlockAsync(string key) { string lockKey = LOCK_NAME + key; await CsRedisManager.DelAsync(lockKey); }