Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Experimental new version using ValueTask #266

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
4 changes: 2 additions & 2 deletions Nito.AsyncEx.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30517.126
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FBBB0AFC-0473-47AC-A5F8-235524DF8A8A}"
EndProject
Expand Down
115 changes: 49 additions & 66 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,76 +1,59 @@
<Project>
<!--
<!--
Directory.Build.props (src) v2.1
- 2.1 Specify LangVersion (required by Nullable for most libraries).
- 2.0 Move project-specific properties to `project.props`.
- 1.1 Remove workaround for .NET SDK bug that was necesary for coverlet to work.
- 1.0 Initial release.
-->

<Import Project="$(MSBuildThisFileDirectory)project.props" />
<Import Project="$(MSBuildThisFileDirectory)project.props" />

<!-- Project quality settings -->
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(CI)'=='true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

<!-- Package settings -->
<PropertyGroup>
<PackageProjectUrl>https://github.com/$(GITHUB_REPOSITORY)</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<!-- Icon file -->
<PropertyGroup>
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<None Include="..\icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<!-- Source debugging -->
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<!-- Versioning -->
<PropertyGroup Condition="'$(CI)'!='true'">
<VersionSuffix>dev</VersionSuffix>
</PropertyGroup>

<!-- Enable coverlet analysis on deterministic builds: https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/DeterministicBuild.md -->
<ItemGroup>
<SourceRoot Include="$(NuGetPackageRoot)" />
</ItemGroup>

<!-- Project quality settings -->
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(CI)'=='true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<!-- Package settings -->
<PropertyGroup>
<PackageProjectUrl>https://github.com/$(GITHUB_REPOSITORY)</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<!-- Icon file -->
<PropertyGroup>
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<None Include="..\icon.png" Pack="true" PackagePath="\"/>
</ItemGroup>

<!-- Source debugging -->
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>

<!-- Include reference assemblies -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>

<!-- Versioning -->
<PropertyGroup Condition="'$(CI)'!='true'">
<VersionSuffix>dev</VersionSuffix>
</PropertyGroup>

<!-- Enable coverlet analysis on deterministic builds: https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/DeterministicBuild.md -->
<ItemGroup>
<SourceRoot Include="$(NuGetPackageRoot)" />
</ItemGroup>
<Target Name="CoverletGetPathMap"
DependsOnTargets="InitializeSourceRootMappedPaths"
Returns="@(_LocalTopLevelSourceRoot)"
Condition="'$(DeterministicSourcePaths)' == 'true'">
<ItemGroup>
<_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
</ItemGroup>
</Target>
</Project>
17 changes: 8 additions & 9 deletions src/Nito.AsyncEx.Context/Nito.AsyncEx.Context.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>A single-threaded async-compatible context.</Description>
<TargetFrameworks>netstandard1.3;netstandard2.0;net461</TargetFrameworks>
<PackageTags>$(PackageTags);synchronizationcontext</PackageTags>
</PropertyGroup>
<PropertyGroup>
<Description>A single-threaded async-compatible context.</Description>
<PackageTags>$(PackageTags);synchronizationcontext</PackageTags>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Tasks\Nito.AsyncEx.Tasks.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Tasks\Nito.AsyncEx.Tasks.csproj" />
</ItemGroup>

</Project>
</Project>
18 changes: 11 additions & 7 deletions src/Nito.AsyncEx.Coordination/AsyncLock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,22 @@ public int Id
/// </summary>
/// <param name="cancellationToken">The cancellation token used to cancel the lock. If this is already set, then this method will attempt to take the lock immediately (succeeding if the lock is currently available).</param>
/// <returns>A disposable that releases the lock when disposed.</returns>
private Task<IDisposable> RequestLockAsync(CancellationToken cancellationToken)
private ValueTask<IDisposable> RequestLockAsync(CancellationToken cancellationToken)
{
lock (_mutex)
{
if (!_taken)
{
// If the lock is available, take it immediately.
_taken = true;
return Task.FromResult<IDisposable>(new Key(this));
#pragma warning disable CA2000
return new ValueTask<IDisposable>(new Key(this));
#pragma warning restore CA2000
}
else
{
// Wait for the lock to become available or cancellation.
return _queue.Enqueue(_mutex, cancellationToken);
return new ValueTask<IDisposable>(_queue.Enqueue(_mutex, cancellationToken));
}
}
}
Expand All @@ -120,16 +122,16 @@ private Task<IDisposable> RequestLockAsync(CancellationToken cancellationToken)
/// </summary>
/// <param name="cancellationToken">The cancellation token used to cancel the lock. If this is already set, then this method will attempt to take the lock immediately (succeeding if the lock is currently available).</param>
/// <returns>A disposable that releases the lock when disposed.</returns>
public AwaitableDisposable<IDisposable> LockAsync(CancellationToken cancellationToken)
public ValueTask<IDisposable> LockAsync(CancellationToken cancellationToken)
{
return new AwaitableDisposable<IDisposable>(RequestLockAsync(cancellationToken));
return RequestLockAsync(cancellationToken);
}

/// <summary>
/// Asynchronously acquires the lock. Returns a disposable that releases the lock when disposed.
/// </summary>
/// <returns>A disposable that releases the lock when disposed.</returns>
public AwaitableDisposable<IDisposable> LockAsync()
public ValueTask<IDisposable> LockAsync()
{
return LockAsync(CancellationToken.None);
}
Expand All @@ -140,7 +142,9 @@ public AwaitableDisposable<IDisposable> LockAsync()
/// <param name="cancellationToken">The cancellation token used to cancel the lock. If this is already set, then this method will attempt to take the lock immediately (succeeding if the lock is currently available).</param>
public IDisposable Lock(CancellationToken cancellationToken)
{
return RequestLockAsync(cancellationToken).WaitAndUnwrapException();
var task = RequestLockAsync(cancellationToken);

return task.IsCompleted ? task.Result : task.AsTask().Result;
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Nito.AsyncEx.Coordination/AsyncMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public int Id
/// </summary>
/// <param name="cancellationToken">The cancellation token used to cancel the enter. If this is already set, then this method will attempt to enter the monitor immediately (succeeding if the monitor is currently available).</param>
/// <returns>A disposable that leaves the monitor when disposed.</returns>
public AwaitableDisposable<IDisposable> EnterAsync(CancellationToken cancellationToken)
public ValueTask<IDisposable> EnterAsync(CancellationToken cancellationToken)
{
return _asyncLock.LockAsync(cancellationToken);
}
Expand All @@ -62,7 +62,7 @@ public AwaitableDisposable<IDisposable> EnterAsync(CancellationToken cancellatio
/// Asynchronously enters the monitor. Returns a disposable that leaves the monitor when disposed.
/// </summary>
/// <returns>A disposable that leaves the monitor when disposed.</returns>
public AwaitableDisposable<IDisposable> EnterAsync()
public ValueTask<IDisposable> EnterAsync()
{
return EnterAsync(CancellationToken.None);
}
Expand Down
12 changes: 6 additions & 6 deletions src/Nito.AsyncEx.Coordination/AsyncReaderWriterLock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,16 @@ private Task<IDisposable> RequestReaderLockAsync(CancellationToken cancellationT
/// </summary>
/// <param name="cancellationToken">The cancellation token used to cancel the lock. If this is already set, then this method will attempt to take the lock immediately (succeeding if the lock is currently available).</param>
/// <returns>A disposable that releases the lock when disposed.</returns>
public AwaitableDisposable<IDisposable> ReaderLockAsync(CancellationToken cancellationToken)
public ValueTask<IDisposable> ReaderLockAsync(CancellationToken cancellationToken)
{
return new AwaitableDisposable<IDisposable>(RequestReaderLockAsync(cancellationToken));
return new ValueTask<IDisposable>(RequestReaderLockAsync(cancellationToken));
}

/// <summary>
/// Asynchronously acquires the lock as a reader. Returns a disposable that releases the lock when disposed.
/// </summary>
/// <returns>A disposable that releases the lock when disposed.</returns>
public AwaitableDisposable<IDisposable> ReaderLockAsync()
public ValueTask<IDisposable> ReaderLockAsync()
{
return ReaderLockAsync(CancellationToken.None);
}
Expand Down Expand Up @@ -198,16 +198,16 @@ private Task<IDisposable> RequestWriterLockAsync(CancellationToken cancellationT
/// </summary>
/// <param name="cancellationToken">The cancellation token used to cancel the lock. If this is already set, then this method will attempt to take the lock immediately (succeeding if the lock is currently available).</param>
/// <returns>A disposable that releases the lock when disposed.</returns>
public AwaitableDisposable<IDisposable> WriterLockAsync(CancellationToken cancellationToken)
public ValueTask<IDisposable> WriterLockAsync(CancellationToken cancellationToken)
{
return new AwaitableDisposable<IDisposable>(RequestWriterLockAsync(cancellationToken));
return new ValueTask<IDisposable>(RequestWriterLockAsync(cancellationToken));
}

/// <summary>
/// Asynchronously acquires the lock as a writer. Returns a disposable that releases the lock when disposed.
/// </summary>
/// <returns>A disposable that releases the lock when disposed.</returns>
public AwaitableDisposable<IDisposable> WriterLockAsync()
public ValueTask<IDisposable> WriterLockAsync()
{
return WriterLockAsync(CancellationToken.None);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Nito.AsyncEx.Coordination/AsyncSemaphore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,17 @@ private async Task<IDisposable> DoLockAsync(CancellationToken cancellationToken)
/// Asynchronously waits on the semaphore, and returns a disposable that releases the semaphore when disposed, thus treating this semaphore as a "multi-lock".
/// </summary>
/// <param name="cancellationToken">The cancellation token used to cancel the wait. If this is already set, then this method will attempt to take the slot immediately (succeeding if a slot is currently available).</param>
public AwaitableDisposable<IDisposable> LockAsync(CancellationToken cancellationToken)
public ValueTask<IDisposable> LockAsync(CancellationToken cancellationToken)
{
#pragma warning disable CA2000 // Dispose objects before losing scope
return new AwaitableDisposable<IDisposable>(DoLockAsync(cancellationToken));
return new ValueTask<IDisposable>(DoLockAsync(cancellationToken));
#pragma warning restore CA2000 // Dispose objects before losing scope
}

/// <summary>
/// Asynchronously waits on the semaphore, and returns a disposable that releases the semaphore when disposed, thus treating this semaphore as a "multi-lock".
/// </summary>
public AwaitableDisposable<IDisposable> LockAsync() => LockAsync(CancellationToken.None);
public ValueTask<IDisposable> LockAsync() => LockAsync(CancellationToken.None);

/// <summary>
/// Synchronously waits on the semaphore, and returns a disposable that releases the semaphore when disposed, thus treating this semaphore as a "multi-lock".
Expand Down
23 changes: 11 additions & 12 deletions src/Nito.AsyncEx.Coordination/Nito.AsyncEx.Coordination.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Asynchronous coordination primitives.</Description>
<TargetFrameworks>netstandard1.3;netstandard2.0;net461</TargetFrameworks>
<PackageTags>$(PackageTags);asynclock;asynclazy</PackageTags>
</PropertyGroup>
<PropertyGroup>
<Description>Asynchronous coordination primitives.</Description>
<PackageTags>$(PackageTags);asynclock;asynclazy</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nito.Collections.Deque" Version="1.1.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Nito.Collections.Deque" Version="1.1.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Tasks\Nito.AsyncEx.Tasks.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Tasks\Nito.AsyncEx.Tasks.csproj" />
</ItemGroup>

</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Task wrappers for WaitHandles.</Description>
<TargetFrameworks>netstandard1.3;netstandard2.0;net461</TargetFrameworks>
<PackageTags>$(PackageTags);waithandle</PackageTags>
</PropertyGroup>
<PropertyGroup>
<Description>Task wrappers for WaitHandles.</Description>
<PackageTags>$(PackageTags);waithandle</PackageTags>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Tasks\Nito.AsyncEx.Tasks.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Tasks\Nito.AsyncEx.Tasks.csproj" />
</ItemGroup>

</Project>
</Project>
15 changes: 7 additions & 8 deletions src/Nito.AsyncEx.Oop/Nito.AsyncEx.Oop.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Interfaces and utility methods for combining async with OOP.</Description>
<TargetFrameworks>netstandard1.3;netstandard2.0;net461</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<Description>Interfaces and utility methods for combining async with OOP.</Description>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Coordination\Nito.AsyncEx.Coordination.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nito.AsyncEx.Coordination\Nito.AsyncEx.Coordination.csproj" />
</ItemGroup>

</Project>
</Project>
Loading