diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs index 7eaed3821b..51066da8a5 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs @@ -6,40 +6,56 @@ namespace Volo.Abp.Threading; public static class SemaphoreSlimExtensions { - public static async Task LockAsync(this SemaphoreSlim semaphoreSlim) + public async static Task LockAsync(this SemaphoreSlim semaphoreSlim) { await semaphoreSlim.WaitAsync(); return GetDispose(semaphoreSlim); } - public static async Task LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) + public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) { await semaphoreSlim.WaitAsync(cancellationToken); return GetDispose(semaphoreSlim); } - public static async Task LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) + public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) { - await semaphoreSlim.WaitAsync(millisecondsTimeout); - return GetDispose(semaphoreSlim); + if (await semaphoreSlim.WaitAsync(millisecondsTimeout)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } - public static async Task LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) + public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) { - await semaphoreSlim.WaitAsync(millisecondsTimeout, cancellationToken); - return GetDispose(semaphoreSlim); + if (await semaphoreSlim.WaitAsync(millisecondsTimeout, cancellationToken)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } - public static async Task LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) + public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) { - await semaphoreSlim.WaitAsync(timeout); - return GetDispose(semaphoreSlim); + if (await semaphoreSlim.WaitAsync(timeout)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } - public static async Task LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) + public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) { - await semaphoreSlim.WaitAsync(timeout, cancellationToken); - return GetDispose(semaphoreSlim); + if (await semaphoreSlim.WaitAsync(timeout, cancellationToken)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } public static IDisposable Lock(this SemaphoreSlim semaphoreSlim) @@ -56,26 +72,42 @@ public static class SemaphoreSlimExtensions public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) { - semaphoreSlim.Wait(millisecondsTimeout); - return GetDispose(semaphoreSlim); + if (semaphoreSlim.Wait(millisecondsTimeout)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) { - semaphoreSlim.Wait(millisecondsTimeout, cancellationToken); - return GetDispose(semaphoreSlim); + if (semaphoreSlim.Wait(millisecondsTimeout, cancellationToken)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) { - semaphoreSlim.Wait(timeout); - return GetDispose(semaphoreSlim); + if (semaphoreSlim.Wait(timeout)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) { - semaphoreSlim.Wait(timeout, cancellationToken); - return GetDispose(semaphoreSlim); + if (semaphoreSlim.Wait(timeout, cancellationToken)) + { + return GetDispose(semaphoreSlim); + } + + throw new TimeoutException(); } private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim) diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Threading/SemaphoreSlimExtensions_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Threading/SemaphoreSlimExtensions_Tests.cs new file mode 100644 index 0000000000..d230a8b924 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Threading/SemaphoreSlimExtensions_Tests.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Threading; + +public class SemaphoreSlimExtensions_Tests +{ + [Fact] + public async Task LockAsync_Test() + { + var semaphore = new SemaphoreSlim(0, 1); + + await Assert.ThrowsAsync(async () => + { + await semaphore.LockAsync(10); + }); + + semaphore = new SemaphoreSlim(1, 1); + using (await semaphore.LockAsync()) + { + semaphore.CurrentCount.ShouldBe(0); + } + semaphore.CurrentCount.ShouldBe(1); + } +}