diff options
author | Stephen Toub <stoub@microsoft.com> | 2017-10-30 22:02:02 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-30 22:02:02 +0300 |
commit | 9a90c2e1fcfb3276275a39f6cdc383e8a3012df0 (patch) | |
tree | f45a933c6bee0c6840b13495d8dcbd1c3f3bd8d2 /src | |
parent | 51a96959a764e25932735f22fa41b93a960b241f (diff) |
Address System.Threading.Channels PR feedback (#24955)
Addressing a few pieces of feedback on the previous PR, plus some auto-cleanup.
Diffstat (limited to 'src')
12 files changed, 97 insertions, 67 deletions
diff --git a/src/System.Threading.Channels/System.Threading.Channels.sln b/src/System.Threading.Channels/System.Threading.Channels.sln index 7a2097ca9f..345b2b9f2e 100644 --- a/src/System.Threading.Channels/System.Threading.Channels.sln +++ b/src/System.Threading.Channels/System.Threading.Channels.sln @@ -1,13 +1,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27019.1 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Channels.Tests", "tests\System.Threading.Channels.Tests.csproj", "{95DFC527-4DC1-495E-97D7-E94EE1F7140D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Channels.Tests", "tests\System.Threading.Channels.Tests.csproj", "{9E984EB2-827E-4029-9647-FB5F8B67C553}" ProjectSection(ProjectDependencies) = postProject - {1DD0FF15-6234-4BD6-850A-317F05479554} = {1DD0FF15-6234-4BD6-850A-317F05479554} + {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977} = {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Channels", "src\System.Threading.Channels.csproj", "{1DD0FF15-6234-4BD6-850A-317F05479554}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Channels", "src\System.Threading.Channels.csproj", "{1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}" ProjectSection(ProjectDependencies) = postProject {9C524CA0-92FF-437B-B568-BCE8A794A69A} = {9C524CA0-92FF-437B-B568-BCE8A794A69A} EndProjectSection @@ -18,47 +18,33 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1A2F9F4A EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - netstandard-Debug|Any CPU = netstandard-Debug|Any CPU - netstandard-Release|Any CPU = netstandard-Release|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.netstandard-Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.netstandard-Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.netstandard-Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.netstandard-Release|Any CPU.Build.0 = netstandard-Release|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU - {95DFC527-4DC1-495E-97D7-E94EE1F7140D}.Release|Any CPU.Build.0 = netstandard-Release|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.Debug|Any CPU.ActiveCfg = netstandard1.3-Debug|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.Debug|Any CPU.Build.0 = netstandard1.3-Debug|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.netstandard-Debug|Any CPU.ActiveCfg = netstandard1.3-Release|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.netstandard-Debug|Any CPU.Build.0 = netstandard1.3-Release|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.netstandard-Release|Any CPU.ActiveCfg = netstandard1.3-Release|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.netstandard-Release|Any CPU.Build.0 = netstandard1.3-Release|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.Release|Any CPU.ActiveCfg = netstandard1.3-Release|Any CPU - {1DD0FF15-6234-4BD6-850A-317F05479554}.Release|Any CPU.Build.0 = netstandard1.3-Release|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Debug|Any CPU.ActiveCfg = netstandard1.3-Debug|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Debug|Any CPU.Build.0 = netstandard1.3-Debug|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.netstandard-Debug|Any CPU.ActiveCfg = netstandard1.3-Release|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.netstandard-Debug|Any CPU.Build.0 = netstandard1.3-Release|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.netstandard-Release|Any CPU.ActiveCfg = netstandard1.3-Release|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.netstandard-Release|Any CPU.Build.0 = netstandard1.3-Release|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Release|Any CPU.ActiveCfg = netstandard1.3-Release|Any CPU - {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Release|Any CPU.Build.0 = netstandard1.3-Release|Any CPU + {9E984EB2-827E-4029-9647-FB5F8B67C553}.Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU + {9E984EB2-827E-4029-9647-FB5F8B67C553}.Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU + {9E984EB2-827E-4029-9647-FB5F8B67C553}.Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU + {9E984EB2-827E-4029-9647-FB5F8B67C553}.Release|Any CPU.Build.0 = netstandard-Release|Any CPU + {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}.Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU + {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}.Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU + {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}.Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU + {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}.Release|Any CPU.Build.0 = netstandard-Release|Any CPU + {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU + {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU + {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU + {9C524CA0-92FF-437B-B568-BCE8A794A69A}.Release|Any CPU.Build.0 = netstandard-Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {95DFC527-4DC1-495E-97D7-E94EE1F7140D} = {1A2F9F4A-A032-433E-B914-ADD5992BB178} - {1DD0FF15-6234-4BD6-850A-317F05479554} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {83C15975-72A6-4FC2-9694-46EF0F4C7A3D} + {9E984EB2-827E-4029-9647-FB5F8B67C553} = {1A2F9F4A-A032-433E-B914-ADD5992BB178} + {1032D5F6-5AE7-4002-A0E4-FEBEADFEA977} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD} + {9C524CA0-92FF-437B-B568-BCE8A794A69A} = {2E666815-2EDB-464B-9DF6-380BF4789AD4} EndGlobalSection EndGlobal diff --git a/src/System.Threading.Channels/pkg/System.Threading.Channels.pkgproj b/src/System.Threading.Channels/pkg/System.Threading.Channels.pkgproj index c96fb26052..6385a6ce73 100644 --- a/src/System.Threading.Channels/pkg/System.Threading.Channels.pkgproj +++ b/src/System.Threading.Channels/pkg/System.Threading.Channels.pkgproj @@ -1,10 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> - <PropertyGroup> - <!-- we need to be supported on pre-nuget-3 platforms (Dev12, Dev11, etc) --> - <MinClientVersion>2.8.6</MinClientVersion> - </PropertyGroup> <ItemGroup> <ProjectReference Include="..\src\System.Threading.Channels.csproj"> <SupportedFramework>netcoreapp2.0;net461;$(AllXamarinFrameworks)</SupportedFramework> diff --git a/src/System.Threading.Channels/ref/System.Threading.Channels.csproj b/src/System.Threading.Channels/ref/System.Threading.Channels.csproj index 557c7f0f2d..fcf8a6961c 100644 --- a/src/System.Threading.Channels/ref/System.Threading.Channels.csproj +++ b/src/System.Threading.Channels/ref/System.Threading.Channels.csproj @@ -4,8 +4,8 @@ <PropertyGroup> <ProjectGuid>{9C524CA0-92FF-437B-B568-BCE8A794A69A}</ProjectGuid> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Debug|AnyCPU'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Release|AnyCPU'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> <ItemGroup> <Compile Include="System.Threading.Channels.cs" /> </ItemGroup> diff --git a/src/System.Threading.Channels/src/System.Threading.Channels.csproj b/src/System.Threading.Channels/src/System.Threading.Channels.csproj index deac429f30..0ae617c778 100644 --- a/src/System.Threading.Channels/src/System.Threading.Channels.csproj +++ b/src/System.Threading.Channels/src/System.Threading.Channels.csproj @@ -2,12 +2,12 @@ <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> - <ProjectGuid>{1DD0FF15-6234-4BD6-850A-317F05479554}</ProjectGuid> + <ProjectGuid>{1032D5F6-5AE7-4002-A0E4-FEBEADFEA977}</ProjectGuid> <RootNamespace>System.Threading.Channels</RootNamespace> <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Debug|AnyCPU'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Release|AnyCPU'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> <ItemGroup> <Compile Include="System\VoidResult.cs" /> <Compile Include="System\Collections\Generic\Dequeue.cs" /> @@ -42,4 +42,4 @@ <Reference Include="System.Threading.Tasks.Extensions" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> -</Project> +</Project>
\ No newline at end of file diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs b/src/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs index 0b7ea44064..23047aba28 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/BoundedChannel.cs @@ -131,7 +131,7 @@ namespace System.Threading.Channels while (!parent._blockedWriters.IsEmpty) { WriterInteractor<T> w = parent._blockedWriters.DequeueHead(); - if (w.Success(default(VoidResult))) + if (w.Success(default)) { parent._items.EnqueueTail(w.Item); return item; @@ -294,7 +294,7 @@ namespace System.Threading.Channels } // We're still allowed to write, but there's no space, so ensure a waiter is queued and return it. - return ChannelUtilities.GetOrCreateWaiter(ref parent._waitingWriters, true, cancellationToken); + return ChannelUtilities.GetOrCreateWaiter(ref parent._waitingWriters, runContinuationsAsynchronously: true, cancellationToken); } } @@ -346,7 +346,7 @@ namespace System.Threading.Channels { // The channel is full and we're in a wait mode. // Queue the writer. - var writer = WriterInteractor<T>.Create(true, cancellationToken, item); + var writer = WriterInteractor<T>.Create(runContinuationsAsynchronously: true, item, cancellationToken); parent._blockedWriters.EnqueueTail(writer); return writer.Task; } diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/ChannelReader.cs b/src/System.Threading.Channels/src/System/Threading/Channels/ChannelReader.cs index a5d7d806ce..bed066ea00 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/ChannelReader.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/ChannelReader.cs @@ -29,6 +29,6 @@ namespace System.Threading.Channels /// A <see cref="Task{Boolean}"/> that will complete with a <c>true</c> result when data is available to read /// or with a <c>false</c> result when no further data will ever be available to be read. /// </returns> - public abstract Task<bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken)); + public abstract Task<bool> WaitToReadAsync(CancellationToken cancellationToken = default); } } diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/ChannelUtilities.cs b/src/System.Threading.Channels/src/System/Threading/Channels/ChannelUtilities.cs index 07995d5659..f802a74bf4 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/ChannelUtilities.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/ChannelUtilities.cs @@ -14,9 +14,9 @@ namespace System.Threading.Channels /// <summary>Sentinel object used to indicate being done writing.</summary> internal static readonly Exception s_doneWritingSentinel = new Exception(nameof(s_doneWritingSentinel)); /// <summary>A cached task with a Boolean true result.</summary> - internal static readonly Task<bool> s_trueTask = Task.FromResult(true); + internal static readonly Task<bool> s_trueTask = Task.FromResult(result: true); /// <summary>A cached task with a Boolean false result.</summary> - internal static readonly Task<bool> s_falseTask = Task.FromResult(false); + internal static readonly Task<bool> s_falseTask = Task.FromResult(result: false); /// <summary>A cached task that never completes.</summary> internal static readonly Task s_neverCompletingTask = new TaskCompletionSource<bool>().Task; @@ -40,7 +40,7 @@ namespace System.Threading.Channels } else { - tcs.TrySetResult(default(VoidResult)); + tcs.TrySetResult(default); } } diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/ChannelWriter.cs b/src/System.Threading.Channels/src/System/Threading/Channels/ChannelWriter.cs index e96c1fff75..d09fa1b0d0 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/ChannelWriter.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/ChannelWriter.cs @@ -31,13 +31,13 @@ namespace System.Threading.Channels /// A <see cref="Task{Boolean}"/> that will complete with a <c>true</c> result when space is available to write an item /// or with a <c>false</c> result when no further writing will be permitted. /// </returns> - public abstract Task<bool> WaitToWriteAsync(CancellationToken cancellationToken = default(CancellationToken)); + public abstract Task<bool> WaitToWriteAsync(CancellationToken cancellationToken = default); /// <summary>Asynchronously writes an item to the channel.</summary> /// <param name="item">The value to write to the channel.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the write operation.</param> /// <returns>A <see cref="Task"/> that represents the asynchronous write operation.</returns> - public virtual Task WriteAsync(T item, CancellationToken cancellationToken = default(CancellationToken)) + public virtual Task WriteAsync(T item, CancellationToken cancellationToken = default) { try { diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/Interactor.cs b/src/System.Threading.Channels/src/System/Threading/Channels/Interactor.cs index cac9aaa62e..f4e0c74767 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/Interactor.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/Interactor.cs @@ -6,46 +6,78 @@ using System.Threading.Tasks; namespace System.Threading.Channels { + /// <summary>A base class for a blocked or waiting reader or writer.</summary> + /// <typeparam name="T">Specifies the type of data passed to the reader or writer.</typeparam> internal abstract class Interactor<T> : TaskCompletionSource<T> { + /// <summary>Initializes the interactor.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> protected Interactor(bool runContinuationsAsynchronously) : base(runContinuationsAsynchronously ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None) { } + /// <summary>Completes the interactor with a success state and the specified result.</summary> + /// <param name="item">The result value.</param> + /// <returns>true if the interactor could be successfully transitioned to a completed state; false if it was already completed.</returns> internal bool Success(T item) { UnregisterCancellation(); return TrySetResult(item); } + /// <summary>Completes the interactor with a failed state and the specified error.</summary> + /// <param name="exception">The error.</param> + /// <returns>true if the interactor could be successfully transitioned to a completed state; false if it was already completed.</returns> internal bool Fail(Exception exception) { UnregisterCancellation(); return TrySetException(exception); } + /// <summary>Unregister cancellation in case cancellation was registered.</summary> internal virtual void UnregisterCancellation() { } } + /// <summary>A blocked or waiting reader.</summary> + /// <typeparam name="T">Specifies the type of data being read.</typeparam> internal class ReaderInteractor<T> : Interactor<T> { + /// <summary>Initializes the reader.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> protected ReaderInteractor(bool runContinuationsAsynchronously) : base(runContinuationsAsynchronously) { } + /// <summary>Creates a reader.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> + /// <returns>The reader.</returns> public static ReaderInteractor<T> Create(bool runContinuationsAsynchronously) => new ReaderInteractor<T>(runContinuationsAsynchronously); + /// <summary>Creates a reader.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> + /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the read operation.</param> + /// <returns>The reader.</returns> public static ReaderInteractor<T> Create(bool runContinuationsAsynchronously, CancellationToken cancellationToken) => cancellationToken.CanBeCanceled ? new CancelableReaderInteractor<T>(runContinuationsAsynchronously, cancellationToken) : new ReaderInteractor<T>(runContinuationsAsynchronously); } + /// <summary>A blocked or waiting writer.</summary> + /// <typeparam name="T">Specifies the type of data being written.</typeparam> internal class WriterInteractor<T> : Interactor<VoidResult> { + /// <summary>Initializes the writer.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> protected WriterInteractor(bool runContinuationsAsynchronously) : base(runContinuationsAsynchronously) { } + /// <summary>The item being written.</summary> internal T Item { get; private set; } - public static WriterInteractor<T> Create(bool runContinuationsAsynchronously, CancellationToken cancellationToken, T item) + /// <summary>Creates a writer.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> + /// <param name="item">The item being written.</param> + /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the read operation.</param> + /// <returns>The reader.</returns> + public static WriterInteractor<T> Create(bool runContinuationsAsynchronously, T item, CancellationToken cancellationToken) { WriterInteractor<T> w = cancellationToken.CanBeCanceled ? new CancelableWriter<T>(runContinuationsAsynchronously, cancellationToken) : @@ -55,11 +87,18 @@ namespace System.Threading.Channels } } + /// <summary>A blocked or waiting reader where the read can be canceled.</summary> + /// <typeparam name="T">Specifies the type of data being read.</typeparam> internal sealed class CancelableReaderInteractor<T> : ReaderInteractor<T> { - private CancellationToken _token; + /// <summary>The token used for cancellation.</summary> + private readonly CancellationToken _token; + /// <summary>Registration in <see cref="_token"/> that should be disposed of when the operation has completed.</summary> private CancellationTokenRegistration _registration; + /// <summary>Initializes the cancelable reader.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> + /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the read operation.</param> internal CancelableReaderInteractor(bool runContinuationsAsynchronously, CancellationToken cancellationToken) : base(runContinuationsAsynchronously) { _token = cancellationToken; @@ -70,18 +109,26 @@ namespace System.Threading.Channels }, this); } + /// <summary>Unregister cancellation in case cancellation was registered.</summary> internal override void UnregisterCancellation() { _registration.Dispose(); - _registration = default(CancellationTokenRegistration); + _registration = default; } } + /// <summary>A blocked or waiting reader where the read can be canceled.</summary> + /// <typeparam name="T">Specifies the type of data being read.</typeparam> internal sealed class CancelableWriter<T> : WriterInteractor<T> { + /// <summary>The token used for cancellation.</summary> private CancellationToken _token; + /// <summary>Registration in <see cref="_token"/> that should be disposed of when the operation has completed.</summary> private CancellationTokenRegistration _registration; + /// <summary>Initializes the cancelable writer.</summary> + /// <param name="runContinuationsAsynchronously">true if continuations should be forced to run asynchronously; otherwise, false.</param> + /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the read operation.</param> internal CancelableWriter(bool runContinuationsAsynchronously, CancellationToken cancellationToken) : base(runContinuationsAsynchronously) { _token = cancellationToken; @@ -92,10 +139,11 @@ namespace System.Threading.Channels }, this); } + /// <summary>Unregister cancellation in case cancellation was registered.</summary> internal override void UnregisterCancellation() { _registration.Dispose(); - _registration = default(CancellationTokenRegistration); + _registration = default; } } } diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/SingleConsumerUnboundedChannel.cs b/src/System.Threading.Channels/src/System/Threading/Channels/SingleConsumerUnboundedChannel.cs index 126cc72269..b3435b88ae 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/SingleConsumerUnboundedChannel.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/SingleConsumerUnboundedChannel.cs @@ -159,7 +159,7 @@ namespace System.Threading.Channels } else { - waitingReader.Success(false); + waitingReader.Success(item: false); } } @@ -197,7 +197,7 @@ namespace System.Threading.Channels // If we get here, we grabbed a waiting reader. // Notify it that an item was written and exit. Debug.Assert(waitingReader != null, "Expected a waiting reader"); - waitingReader.Success(true); + waitingReader.Success(item: true); return true; } } diff --git a/src/System.Threading.Channels/src/System/Threading/Channels/UnbufferedChannel.cs b/src/System.Threading.Channels/src/System/Threading/Channels/UnbufferedChannel.cs index 9a7e5b8b51..209ee2abd6 100644 --- a/src/System.Threading.Channels/src/System/Threading/Channels/UnbufferedChannel.cs +++ b/src/System.Threading.Channels/src/System/Threading/Channels/UnbufferedChannel.cs @@ -39,7 +39,7 @@ namespace System.Threading.Channels while (!parent._blockedWriters.IsEmpty) { WriterInteractor<T> w = parent._blockedWriters.DequeueHead(); - if (w.Success(default(VoidResult))) + if (w.Success(default)) { item = w.Item; return true; @@ -77,7 +77,7 @@ namespace System.Threading.Channels } // Otherwise, queue the waiter. - return ChannelUtilities.GetOrCreateWaiter(ref parent._waitingReaders, true, cancellationToken); + return ChannelUtilities.GetOrCreateWaiter(ref parent._waitingReaders, runContinuationsAsynchronously: true, cancellationToken); } } } @@ -157,7 +157,7 @@ namespace System.Threading.Channels if (parent._completion.Task.IsCompleted) { return - parent._completion.Task.IsCanceled ? Task.FromCanceled<T>(new CancellationToken(true)) : + parent._completion.Task.IsCanceled ? Task.FromCanceled<T>(new CancellationToken(canceled: true)) : Task.FromException<T>( parent._completion.Task.IsFaulted ? ChannelUtilities.CreateInvalidCompletionException(parent._completion.Task.Exception.InnerException) : @@ -165,7 +165,7 @@ namespace System.Threading.Channels } // Queue the writer. - var w = WriterInteractor<T>.Create(true, cancellationToken, item); + var w = WriterInteractor<T>.Create(runContinuationsAsynchronously: true, item, cancellationToken); parent._blockedWriters.EnqueueTail(w); // And let any waiting readers know it's their lucky day. diff --git a/src/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj b/src/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj index 80f88a1d6d..a1c44438c4 100644 --- a/src/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj +++ b/src/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj @@ -2,7 +2,7 @@ <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> - <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <ProjectGuid>{9E984EB2-827E-4029-9647-FB5F8B67C553}</ProjectGuid> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> @@ -20,4 +20,4 @@ </Compile> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> -</Project> +</Project>
\ No newline at end of file |