using Microsoft.AspNetCore.DataProtection.KeyManagement; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using XF.Domain.Exceptions; namespace XF.Domain.Locks { public interface IDistributedLock { public bool Acquire(string key, TimeSpan expired); public Task AcquireAsync(string key, TimeSpan expired, CancellationToken cancellationToken); public void Release(string key); public Task ReleaseAsync(string key, CancellationToken cancellationToken); } public class LockManager : IDisposable { private readonly IDistributedLock _locker; private readonly string _key; public LockManager(IDistributedLock locker, string key) { _locker = locker; _key = key; } /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public void Dispose() { _locker.Release(_key); } public void InvokeInLock(Action doSome, TimeSpan expired) { if (_locker.Acquire(_key, expired)) { try { doSome(); } catch (Exception e) { Console.WriteLine(e); throw; } finally { _locker.Release(_key); } } else { throw new UserFriendlyException("系统忙,请稍后重试"); } } public async Task InvokeInLockAsync(Func doSome, TimeSpan expired, CancellationToken cancellationToken) { if (await _locker.AcquireAsync(_key, expired, cancellationToken)) { try { await doSome(cancellationToken); } catch (Exception e) { Console.WriteLine(e); throw; } finally { await _locker.ReleaseAsync(_key, cancellationToken); } } else { throw new UserFriendlyException("系统忙,请稍后重试"); } } } }