From 45a79470f8b28daf89ca58355edb74d36fe3cbda Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Sun, 13 Oct 2024 12:31:30 +0200 Subject: [PATCH] Improved performance for SemaphoreSlim locking. --- Directory.Packages.props | 1 + .../src/Volo.Abp.Core/Volo.Abp.Core.csproj | 5 ++- .../Abp/Threading/SemaphoreSlimExtensions.cs | 38 +++++++++++++------ .../LocalAbpDistributedLock.cs | 2 +- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2498cc1a28..3ad8cffd50 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -166,6 +166,7 @@ + diff --git a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj index edb61d6a21..4001822502 100644 --- a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj +++ b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj @@ -4,7 +4,7 @@ - netstandard2.0;netstandard2.1;net8.0;net9.0 + netstandard2.0;netstandard2.1;net5.0;net8.0;net9.0 enable Nullable Volo.Abp.Core @@ -33,6 +33,9 @@ + + + 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 51066da8a5..30482811b2 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -6,21 +7,24 @@ namespace Volo.Abp.Threading; public static class SemaphoreSlimExtensions { - public async static Task LockAsync(this SemaphoreSlim semaphoreSlim) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public async static ValueTask LockAsync(this SemaphoreSlim semaphoreSlim) { - await semaphoreSlim.WaitAsync(); + await semaphoreSlim.WaitAsync().ConfigureAwait(false); return GetDispose(semaphoreSlim); } - public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public async static ValueTask LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) { - await semaphoreSlim.WaitAsync(cancellationToken); + await semaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false); return GetDispose(semaphoreSlim); } - public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public async static ValueTask LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) { - if (await semaphoreSlim.WaitAsync(millisecondsTimeout)) + if (await semaphoreSlim.WaitAsync(millisecondsTimeout).ConfigureAwait(false)) { return GetDispose(semaphoreSlim); } @@ -28,9 +32,10 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } - public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public async static ValueTask LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) { - if (await semaphoreSlim.WaitAsync(millisecondsTimeout, cancellationToken)) + if (await semaphoreSlim.WaitAsync(millisecondsTimeout, cancellationToken).ConfigureAwait(false)) { return GetDispose(semaphoreSlim); } @@ -38,9 +43,10 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } - public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public async static ValueTask LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) { - if (await semaphoreSlim.WaitAsync(timeout)) + if (await semaphoreSlim.WaitAsync(timeout).ConfigureAwait(false)) { return GetDispose(semaphoreSlim); } @@ -48,9 +54,10 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } - public async static Task LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public async static ValueTask LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) { - if (await semaphoreSlim.WaitAsync(timeout, cancellationToken)) + if (await semaphoreSlim.WaitAsync(timeout, cancellationToken).ConfigureAwait(false)) { return GetDispose(semaphoreSlim); } @@ -58,18 +65,21 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IDisposable Lock(this SemaphoreSlim semaphoreSlim) { semaphoreSlim.Wait(); return GetDispose(semaphoreSlim); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) { semaphoreSlim.Wait(cancellationToken); return GetDispose(semaphoreSlim); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) { if (semaphoreSlim.Wait(millisecondsTimeout)) @@ -80,6 +90,7 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) { if (semaphoreSlim.Wait(millisecondsTimeout, cancellationToken)) @@ -90,6 +101,7 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) { if (semaphoreSlim.Wait(timeout)) @@ -100,6 +112,7 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) { if (semaphoreSlim.Wait(timeout, cancellationToken)) @@ -110,6 +123,7 @@ public static class SemaphoreSlimExtensions throw new TimeoutException(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim) { return new DisposeAction(static (semaphoreSlim) => diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs index 58d67e1caf..e9913160de 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs @@ -30,7 +30,7 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency Check.NotNullOrWhiteSpace(name, nameof(name)); var key = DistributedLockKeyNormalizer.NormalizeKey(name); - var timeoutReleaser = await _localSyncObjects.LockAsync(key, timeout, cancellationToken); + var timeoutReleaser = await _localSyncObjects.LockAsync(key, timeout, cancellationToken).ConfigureAwait(false); if (!timeoutReleaser.EnteredSemaphore) { timeoutReleaser.Dispose();