Skip to content

Replace AsyncLock with SemaphoreSlim #22791

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
1 commit merged into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ root = false
# Code files
[*.cs]

# Design rules

# CA1001: Types that own disposable fields should be disposable
dotnet_diagnostic.CA1001.severity = error

# Globalization rules

# CA1303: Do not pass literals as localized parameters
Expand Down
91 changes: 0 additions & 91 deletions src/EFCore/Internal/AsyncLock.cs

This file was deleted.

23 changes: 19 additions & 4 deletions src/EFCore/ValueGeneration/HiLoValueGeneratorState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ namespace Microsoft.EntityFrameworkCore.ValueGeneration
/// <summary>
/// The thread safe state used by <see cref="HiLoValueGenerator{TValue}" />.
/// </summary>
public class HiLoValueGeneratorState
public class HiLoValueGeneratorState : IDisposable
{
private readonly AsyncLock _asyncLock = new AsyncLock();
private readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1);
private HiLoValue _currentValue;
private readonly int _blockSize;

Expand Down Expand Up @@ -58,7 +58,8 @@ public virtual TValue Next<TValue>([NotNull] Func<long> getNewLowValue)
// gets a chance to use the new value, so use a while here to do it all again.
while (newValue.Low >= newValue.High)
{
using (_asyncLock.Lock())
_semaphoreSlim.Wait();
try
{
// Once inside the lock check to see if another thread already got a new block, in which
// case just get a value out of the new block instead of requesting one.
Expand All @@ -73,6 +74,10 @@ public virtual TValue Next<TValue>([NotNull] Func<long> getNewLowValue)
newValue = GetNextValue();
}
}
finally
{
_semaphoreSlim.Release();
}
}

return ConvertResult<TValue>(newValue);
Expand Down Expand Up @@ -100,7 +105,8 @@ public virtual async ValueTask<TValue> NextAsync<TValue>(
// gets a chance to use the new value, so use a while here to do it all again.
while (newValue.Low >= newValue.High)
{
using (await _asyncLock.LockAsync(cancellationToken).ConfigureAwait(false))
await _semaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
// Once inside the lock check to see if another thread already got a new block, in which
// case just get a value out of the new block instead of requesting one.
Expand All @@ -115,6 +121,10 @@ public virtual async ValueTask<TValue> NextAsync<TValue>(
newValue = GetNextValue();
}
}
finally
{
_semaphoreSlim.Release();
}
}

return ConvertResult<TValue>(newValue);
Expand Down Expand Up @@ -152,5 +162,10 @@ public HiLoValue(long low, long high)
public HiLoValue NextValue()
=> new HiLoValue(Low + 1, High);
}

/// <summary>
/// Releases the allocated resources for this instance.
/// </summary>
public virtual void Dispose() => _semaphoreSlim.Dispose();
}
}