Browse Source

Improved performance for SemaphoreSlim locking.

pull/21065/head
Mark Cilia Vincenti 1 year ago
parent
commit
45a79470f8
  1. 1
      Directory.Packages.props
  2. 5
      framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj
  3. 38
      framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs
  4. 2
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs

1
Directory.Packages.props

@ -166,6 +166,7 @@
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.0-rc.1.24431.7" /> <PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.0-rc.1.24431.7" />
<PackageVersion Include="System.Text.Encodings.Web" Version="9.0.0-rc.1.24431.7" /> <PackageVersion Include="System.Text.Encodings.Web" Version="9.0.0-rc.1.24431.7" />
<PackageVersion Include="System.Text.Json" Version="9.0.0-rc.1.24431.7" /> <PackageVersion Include="System.Text.Json" Version="9.0.0-rc.1.24431.7" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.1.0" /> <PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.1.0" />
<PackageVersion Include="TimeZoneConverter" Version="6.1.0" /> <PackageVersion Include="TimeZoneConverter" Version="6.1.0" />
<PackageVersion Include="Unidecode.NET" Version="2.1.0" /> <PackageVersion Include="Unidecode.NET" Version="2.1.0" />

5
framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj

@ -4,7 +4,7 @@
<Import Project="..\..\..\common.props" /> <Import Project="..\..\..\common.props" />
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks> <TargetFrameworks>netstandard2.0;netstandard2.1;net5.0;net8.0;net9.0</TargetFrameworks>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors> <WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.Core</AssemblyName> <AssemblyName>Volo.Abp.Core</AssemblyName>
@ -33,6 +33,9 @@
<PackageReference Include="JetBrains.Annotations" /> <PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="Nito.AsyncEx.Context" /> <PackageReference Include="Nito.AsyncEx.Context" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="System.Threading.Tasks.Extensions" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.1')) "> <ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.1')) ">
<PackageReference Include="System.ComponentModel.Annotations" /> <PackageReference Include="System.ComponentModel.Annotations" />
</ItemGroup> </ItemGroup>

38
framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -6,21 +7,24 @@ namespace Volo.Abp.Threading;
public static class SemaphoreSlimExtensions public static class SemaphoreSlimExtensions
{ {
public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim) [MethodImpl(MethodImplOptions.AggressiveInlining)]
public async static ValueTask<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim)
{ {
await semaphoreSlim.WaitAsync(); await semaphoreSlim.WaitAsync().ConfigureAwait(false);
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) [MethodImpl(MethodImplOptions.AggressiveInlining)]
public async static ValueTask<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken)
{ {
await semaphoreSlim.WaitAsync(cancellationToken); await semaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false);
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) [MethodImpl(MethodImplOptions.AggressiveInlining)]
public async static ValueTask<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout)
{ {
if (await semaphoreSlim.WaitAsync(millisecondsTimeout)) if (await semaphoreSlim.WaitAsync(millisecondsTimeout).ConfigureAwait(false))
{ {
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
@ -28,9 +32,10 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) [MethodImpl(MethodImplOptions.AggressiveInlining)]
public async static ValueTask<IDisposable> 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); return GetDispose(semaphoreSlim);
} }
@ -38,9 +43,10 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) [MethodImpl(MethodImplOptions.AggressiveInlining)]
public async static ValueTask<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout)
{ {
if (await semaphoreSlim.WaitAsync(timeout)) if (await semaphoreSlim.WaitAsync(timeout).ConfigureAwait(false))
{ {
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
@ -48,9 +54,10 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) [MethodImpl(MethodImplOptions.AggressiveInlining)]
public async static ValueTask<IDisposable> 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); return GetDispose(semaphoreSlim);
} }
@ -58,18 +65,21 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim)
{ {
semaphoreSlim.Wait(); semaphoreSlim.Wait();
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken)
{ {
semaphoreSlim.Wait(cancellationToken); semaphoreSlim.Wait(cancellationToken);
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout)
{ {
if (semaphoreSlim.Wait(millisecondsTimeout)) if (semaphoreSlim.Wait(millisecondsTimeout))
@ -80,6 +90,7 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken)
{ {
if (semaphoreSlim.Wait(millisecondsTimeout, cancellationToken)) if (semaphoreSlim.Wait(millisecondsTimeout, cancellationToken))
@ -90,6 +101,7 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout)
{ {
if (semaphoreSlim.Wait(timeout)) if (semaphoreSlim.Wait(timeout))
@ -100,6 +112,7 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken)
{ {
if (semaphoreSlim.Wait(timeout, cancellationToken)) if (semaphoreSlim.Wait(timeout, cancellationToken))
@ -110,6 +123,7 @@ public static class SemaphoreSlimExtensions
throw new TimeoutException(); throw new TimeoutException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim) private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim)
{ {
return new DisposeAction<SemaphoreSlim>(static (semaphoreSlim) => return new DisposeAction<SemaphoreSlim>(static (semaphoreSlim) =>

2
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)); Check.NotNullOrWhiteSpace(name, nameof(name));
var key = DistributedLockKeyNormalizer.NormalizeKey(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) if (!timeoutReleaser.EnteredSemaphore)
{ {
timeoutReleaser.Dispose(); timeoutReleaser.Dispose();

Loading…
Cancel
Save