Use ValueTask shared from corelib (dotnet/corefx#26636)
authorStephen Toub <stoub@microsoft.com>
Thu, 1 Feb 2018 22:22:00 +0000 (17:22 -0500)
committerGitHub <noreply@github.com>
Thu, 1 Feb 2018 22:22:00 +0000 (17:22 -0500)
Commit migrated from https://github.com/dotnet/corefx/commit/7b6abc253912de3caeddfcb06aa3f619255351f7

src/libraries/System.Threading.Tasks.Extensions/src/System.Threading.Tasks.Extensions.csproj
src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs [deleted file]
src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs [deleted file]
src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs [deleted file]
src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs [deleted file]
src/libraries/System.Threading.Tasks.Extensions/src/System/Threading/Tasks/ValueTask.cs [deleted file]
src/libraries/System.Threading.Tasks.Extensions/src/System/ThrowHelper.cs [new file with mode: 0644]
src/libraries/System.Threading.Tasks.Extensions/tests/System.Threading.Tasks.Extensions.Tests.csproj

index 0bc9392..dc43433 100644 (file)
@@ -6,6 +6,7 @@
     <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile>
     <PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard1.0'">netstandard1.0;portable-net45+win8+wp8+wpa81</PackageTargetFramework>
     <IsPartialFacadeAssembly Condition="'$(TargetGroup)' != 'netstandard' and '$(TargetGroup)' != 'netstandard1.0'">true</IsPartialFacadeAssembly>
+    <DefineConstants Condition="'$(IsPartialFacadeAssembly)' != 'true'">$(DefineConstants);netstandard</DefineConstants>
     <ExcludeResourcesImport Condition="'$(IsPartialFacadeAssembly)'=='true'">true</ExcludeResourcesImport>
     <AssemblyVersion Condition="$(TargetGroup.StartsWith('netstandard'))">4.1.1.0</AssemblyVersion>
   </PropertyGroup>
     <ReferenceFromRuntime Include="System.Private.CoreLib" />
   </ItemGroup>
   <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
-    <Compile Include="System\Runtime\CompilerServices\AsyncMethodBuilderAttribute.cs" />
-    <Compile Include="System\Runtime\CompilerServices\AsyncValueTaskMethodBuilder.cs" />
-    <Compile Include="System\Runtime\CompilerServices\ConfiguredValueTaskAwaitable.cs" />
-    <Compile Include="System\Runtime\CompilerServices\ValueTaskAwaiter.cs" />
-    <Compile Include="System\Threading\Tasks\ValueTask.cs" />
+    <Compile Include="System\ThrowHelper.cs" />
+    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\StackTraceHiddenAttribute.cs">
+      <Link>Common\CoreLib\System\Diagnostics\StackTraceHiddenAttribute.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonPath)\CoreLib\System\Runtime\CompilerServices\AsyncMethodBuilderAttribute.cs">
+      <Link>Common\CoreLib\System\Runtime\CompilerServices\AsyncMethodBuilderAttribute.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonPath)\CoreLib\System\Runtime\CompilerServices\AsyncValueTaskMethodBuilder.cs">
+      <Link>Common\CoreLib\System\Runtime\CompilerServices\AsyncValueTaskMethodBuilder.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonPath)\CoreLib\System\Runtime\CompilerServices\ConfiguredValueTaskAwaitable.cs">
+      <Link>Common\CoreLib\System\Runtime\CompilerServices\ConfiguredValueTaskAwaitable.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonPath)\CoreLib\System\Runtime\CompilerServices\ValueTaskAwaiter.cs">
+      <Link>Common\CoreLib\System\Runtime\CompilerServices\ValueTaskAwaiter.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonPath)\CoreLib\System\Threading\Tasks\ValueTask.cs">
+      <Link>Common\CoreLib\System\Threading\Tasks\ValueTask.cs</Link>
+    </Compile>
+
     <Reference Include="System.Collections" />
     <Reference Include="System.Diagnostics.Debug" />
     <Reference Include="System.Runtime" />
     <Reference Include="System.Threading.Tasks" />
   </ItemGroup>
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
\ No newline at end of file
+</Project>
diff --git a/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs b/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs
deleted file mode 100644 (file)
index 688a3a0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices
-{
-    /// <summary>
-    /// Indicates the type of the async method builder that should be used by a language compiler to
-    /// build the attributed type when used as the return type of an async method.
-    /// </summary>
-    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
-    public sealed class AsyncMethodBuilderAttribute : Attribute
-    {
-        /// <summary>Initializes the <see cref="AsyncMethodBuilderAttribute"/>.</summary>
-        /// <param name="builderType">The <see cref="Type"/> of the associated builder.</param>
-        public AsyncMethodBuilderAttribute(Type builderType) => BuilderType = builderType;
-
-        /// <summary>Gets the <see cref="Type"/> of the associated builder.</summary>
-        public Type BuilderType { get; }
-    }
-}
diff --git a/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs b/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/AsyncValueTaskMethodBuilder.cs
deleted file mode 100644 (file)
index 8cbcdc5..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Threading.Tasks;
-
-namespace System.Runtime.CompilerServices
-{
-    /// <summary>Represents a builder for asynchronous methods that returns a <see cref="ValueTask{TResult}"/>.</summary>
-    /// <typeparam name="TResult">The type of the result.</typeparam>
-    [StructLayout(LayoutKind.Auto)]
-    public struct AsyncValueTaskMethodBuilder<TResult>
-    {
-        /// <summary>The <see cref="AsyncTaskMethodBuilder{TResult}"/> to which most operations are delegated.</summary>
-        private AsyncTaskMethodBuilder<TResult> _methodBuilder;
-        /// <summary>The result for this builder, if it's completed before any awaits occur.</summary>
-        private TResult _result;
-        /// <summary>true if <see cref="_result"/> contains the synchronous result for the async method; otherwise, false.</summary>
-        private bool _haveResult;
-        /// <summary>true if the builder should be used for setting/getting the result; otherwise, false.</summary>
-        private bool _useBuilder;
-
-        /// <summary>Creates an instance of the <see cref="AsyncValueTaskMethodBuilder{TResult}"/> struct.</summary>
-        /// <returns>The initialized instance.</returns>
-        public static AsyncValueTaskMethodBuilder<TResult> Create() =>
-            new AsyncValueTaskMethodBuilder<TResult>() { _methodBuilder = AsyncTaskMethodBuilder<TResult>.Create() };
-
-        /// <summary>Begins running the builder with the associated state machine.</summary>
-        /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
-        /// <param name="stateMachine">The state machine instance, passed by reference.</param>
-        public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
-            _methodBuilder.Start(ref stateMachine); // will provide the right ExecutionContext semantics
-
-        /// <summary>Associates the builder with the specified state machine.</summary>
-        /// <param name="stateMachine">The state machine instance to associate with the builder.</param>
-        public void SetStateMachine(IAsyncStateMachine stateMachine) => _methodBuilder.SetStateMachine(stateMachine);
-
-        /// <summary>Marks the task as successfully completed.</summary>
-        /// <param name="result">The result to use to complete the task.</param>
-        public void SetResult(TResult result)
-        {
-            if (_useBuilder)
-            {
-                _methodBuilder.SetResult(result);
-            }
-            else
-            {
-                _result = result;
-                _haveResult = true;
-            }
-        }
-
-        /// <summary>Marks the task as failed and binds the specified exception to the task.</summary>
-        /// <param name="exception">The exception to bind to the task.</param>
-        public void SetException(Exception exception) => _methodBuilder.SetException(exception);
-
-        /// <summary>Gets the task for this builder.</summary>
-        public ValueTask<TResult> Task
-        {
-            get
-            {
-                if (_haveResult)
-                {
-                    return new ValueTask<TResult>(_result);
-                }
-                else
-                {
-                    _useBuilder = true;
-                    return new ValueTask<TResult>(_methodBuilder.Task);
-                }
-            }
-        }
-
-        /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
-        /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
-        /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
-        /// <param name="awaiter">the awaiter</param>
-        /// <param name="stateMachine">The state machine.</param>
-        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
-            where TAwaiter : INotifyCompletion
-            where TStateMachine : IAsyncStateMachine
-        {
-            _useBuilder = true;
-            _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
-        }
-
-        /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
-        /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
-        /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
-        /// <param name="awaiter">the awaiter</param>
-        /// <param name="stateMachine">The state machine.</param>
-        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
-            where TAwaiter : ICriticalNotifyCompletion 
-            where TStateMachine : IAsyncStateMachine
-        {
-            _useBuilder = true;
-            _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
-        }
-    }
-}
diff --git a/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs b/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
deleted file mode 100644 (file)
index e0b92e5..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace System.Runtime.CompilerServices
-{
-    /// <summary>Provides an awaitable type that enables configured awaits on a <see cref="ValueTask{TResult}"/>.</summary>
-    /// <typeparam name="TResult">The type of the result produced.</typeparam>
-    [StructLayout(LayoutKind.Auto)]
-    public readonly struct ConfiguredValueTaskAwaitable<TResult>
-    {
-        /// <summary>The wrapped <see cref="ValueTask{TResult}"/>.</summary>
-        private readonly ValueTask<TResult> _value;
-        /// <summary>true to attempt to marshal the continuation back to the original context captured; otherwise, false.</summary>
-        private readonly bool _continueOnCapturedContext;
-
-        /// <summary>Initializes the awaitable.</summary>
-        /// <param name="value">The wrapped <see cref="ValueTask{TResult}"/>.</param>
-        /// <param name="continueOnCapturedContext">
-        /// true to attempt to marshal the continuation back to the original synchronization context captured; otherwise, false.
-        /// </param>
-        internal ConfiguredValueTaskAwaitable(ValueTask<TResult> value, bool continueOnCapturedContext)
-        {
-            _value = value;
-            _continueOnCapturedContext = continueOnCapturedContext;
-        }
-
-        /// <summary>Returns an awaiter for this <see cref="ConfiguredValueTaskAwaitable{TResult}"/> instance.</summary>
-        public ConfiguredValueTaskAwaiter GetAwaiter() =>
-            new ConfiguredValueTaskAwaiter(_value, _continueOnCapturedContext);
-
-        /// <summary>Provides an awaiter for a <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
-        [StructLayout(LayoutKind.Auto)]
-        public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion
-        {
-            /// <summary>The value being awaited.</summary>
-            private readonly ValueTask<TResult> _value;
-            /// <summary>The value to pass to ConfigureAwait.</summary>
-            private readonly bool _continueOnCapturedContext;
-
-            /// <summary>Initializes the awaiter.</summary>
-            /// <param name="value">The value to be awaited.</param>
-            /// <param name="continueOnCapturedContext">The value to pass to ConfigureAwait.</param>
-            internal ConfiguredValueTaskAwaiter(ValueTask<TResult> value, bool continueOnCapturedContext)
-            {
-                _value = value;
-                _continueOnCapturedContext = continueOnCapturedContext;
-            }
-
-            /// <summary>Gets whether the <see cref="ConfiguredValueTaskAwaitable{TResult}"/> has completed.</summary>
-            public bool IsCompleted => _value.IsCompleted;
-
-            /// <summary>Gets the result of the ValueTask.</summary>
-            public TResult GetResult() =>
-                _value._task == null ? 
-                    _value._result : 
-                    _value._task.GetAwaiter().GetResult();
-
-            /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
-            public void OnCompleted(Action continuation) =>
-                _value.AsTask().ConfigureAwait(_continueOnCapturedContext).GetAwaiter().OnCompleted(continuation);
-
-            /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary>
-            public void UnsafeOnCompleted(Action continuation) =>
-                _value.AsTask().ConfigureAwait(_continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation);
-        }
-    }
-}
diff --git a/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/src/libraries/System.Threading.Tasks.Extensions/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
deleted file mode 100644 (file)
index 2774ba6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace System.Runtime.CompilerServices
-{
-    /// <summary>Provides an awaiter for a <see cref="ValueTask{TResult}"/>.</summary>
-    public readonly struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion
-    {
-        /// <summary>The value being awaited.</summary>
-        private readonly ValueTask<TResult> _value;
-
-        /// <summary>Initializes the awaiter.</summary>
-        /// <param name="value">The value to be awaited.</param>
-        internal ValueTaskAwaiter(ValueTask<TResult> value) => _value = value;
-
-        /// <summary>Gets whether the <see cref="ValueTask{TResult}"/> has completed.</summary>
-        public bool IsCompleted => _value.IsCompleted;
-
-        /// <summary>Gets the result of the ValueTask.</summary>
-        public TResult GetResult() =>
-            _value._task == null ? 
-                _value._result : 
-                _value._task.GetAwaiter().GetResult();
-
-        /// <summary>Schedules the continuation action for this ValueTask.</summary>
-        public void OnCompleted(Action continuation) =>
-            _value.AsTask().ConfigureAwait(continueOnCapturedContext: true).GetAwaiter().OnCompleted(continuation);
-
-        /// <summary>Schedules the continuation action for this ValueTask.</summary>
-        public void UnsafeOnCompleted(Action continuation) =>
-            _value.AsTask().ConfigureAwait(continueOnCapturedContext: true).GetAwaiter().UnsafeOnCompleted(continuation);
-    }
-}
diff --git a/src/libraries/System.Threading.Tasks.Extensions/src/System/Threading/Tasks/ValueTask.cs b/src/libraries/System.Threading.Tasks.Extensions/src/System/Threading/Tasks/ValueTask.cs
deleted file mode 100644 (file)
index f1f7227..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace System.Threading.Tasks
-{
-    /// <summary>
-    /// Provides a value type that wraps a <see cref="Task{TResult}"/> and a <typeparamref name="TResult"/>,
-    /// only one of which is used.
-    /// </summary>
-    /// <typeparam name="TResult">The type of the result.</typeparam>
-    /// <remarks>
-    /// <para>
-    /// Methods may return an instance of this value type when it's likely that the result of their
-    /// operations will be available synchronously and when the method is expected to be invoked so
-    /// frequently that the cost of allocating a new <see cref="Task{TResult}"/> for each call will
-    /// be prohibitive.
-    /// </para>
-    /// <para>
-    /// There are tradeoffs to using a <see cref="ValueTask{TResult}"/> instead of a <see cref="Task{TResult}"/>.
-    /// For example, while a <see cref="ValueTask{TResult}"/> can help avoid an allocation in the case where the 
-    /// successful result is available synchronously, it also contains two fields whereas a <see cref="Task{TResult}"/>
-    /// as a reference type is a single field.  This means that a method call ends up returning two fields worth of
-    /// data instead of one, which is more data to copy.  It also means that if a method that returns one of these
-    /// is awaited within an async method, the state machine for that async method will be larger due to needing
-    /// to store the struct that's two fields instead of a single reference.
-    /// </para>
-    /// <para>
-    /// Further, for uses other than consuming the result of an asynchronous operation via await, 
-    /// <see cref="ValueTask{TResult}"/> can lead to a more convoluted programming model, which can in turn actually 
-    /// lead to more allocations.  For example, consider a method that could return either a <see cref="Task{TResult}"/> 
-    /// with a cached task as a common result or a <see cref="ValueTask{TResult}"/>.  If the consumer of the result 
-    /// wants to use it as a <see cref="Task{TResult}"/>, such as to use with in methods like Task.WhenAll and Task.WhenAny, 
-    /// the <see cref="ValueTask{TResult}"/> would first need to be converted into a <see cref="Task{TResult}"/> using 
-    /// <see cref="ValueTask{TResult}.AsTask"/>, which leads to an allocation that would have been avoided if a cached 
-    /// <see cref="Task{TResult}"/> had been used in the first place.
-    /// </para>
-    /// <para>
-    /// As such, the default choice for any asynchronous method should be to return a <see cref="Task"/> or 
-    /// <see cref="Task{TResult}"/>. Only if performance analysis proves it worthwhile should a <see cref="ValueTask{TResult}"/> 
-    /// be used instead of <see cref="Task{TResult}"/>.  There is no non-generic version of <see cref="ValueTask{TResult}"/> 
-    /// as the Task.CompletedTask property may be used to hand back a successfully completed singleton in the case where
-    /// a <see cref="Task"/>-returning method completes synchronously and successfully.
-    /// </para>
-    /// </remarks>
-    [AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder<>))]
-    [StructLayout(LayoutKind.Auto)]
-    public readonly struct ValueTask<TResult> : IEquatable<ValueTask<TResult>>
-    {
-        /// <summary>The task to be used if the operation completed asynchronously or if it completed synchronously but non-successfully.</summary>
-        internal readonly Task<TResult> _task;
-        /// <summary>The result to be used if the operation completed successfully synchronously.</summary>
-        internal readonly TResult _result;
-
-        /// <summary>Initialize the <see cref="ValueTask{TResult}"/> with the result of the successful operation.</summary>
-        /// <param name="result">The result.</param>
-        public ValueTask(TResult result)
-        {
-            _task = null;
-            _result = result;
-        }
-
-        /// <summary>
-        /// Initialize the <see cref="ValueTask{TResult}"/> with a <see cref="Task{TResult}"/> that represents the operation.
-        /// </summary>
-        /// <param name="task">The task.</param>
-        public ValueTask(Task<TResult> task)
-        {
-            _task = task ?? throw new ArgumentNullException(nameof(task));
-            _result = default(TResult);
-        }
-
-        /// <summary>Returns the hash code for this instance.</summary>
-        public override int GetHashCode() =>
-            _task != null ? _task.GetHashCode() :
-            _result != null ? _result.GetHashCode() :
-            0;
-
-        /// <summary>Returns a value indicating whether this value is equal to a specified <see cref="object"/>.</summary>
-        public override bool Equals(object obj) =>
-            obj is ValueTask<TResult> && 
-            Equals((ValueTask<TResult>)obj);
-
-        /// <summary>Returns a value indicating whether this value is equal to a specified <see cref="ValueTask{TResult}"/> value.</summary>
-        public bool Equals(ValueTask<TResult> other) =>
-            _task != null || other._task != null ? 
-                _task == other._task :
-                EqualityComparer<TResult>.Default.Equals(_result, other._result);
-
-        /// <summary>Returns a value indicating whether two <see cref="ValueTask{TResult}"/> values are equal.</summary>
-        public static bool operator==(ValueTask<TResult> left, ValueTask<TResult> right) =>
-            left.Equals(right);
-
-        /// <summary>Returns a value indicating whether two <see cref="ValueTask{TResult}"/> values are not equal.</summary>
-        public static bool operator!=(ValueTask<TResult> left, ValueTask<TResult> right) =>
-            !left.Equals(right);
-
-        /// <summary>
-        /// Gets a <see cref="Task{TResult}"/> object to represent this ValueTask.  It will
-        /// either return the wrapped task object if one exists, or it'll manufacture a new
-        /// task object to represent the result.
-        /// </summary>
-        public Task<TResult> AsTask() =>
-            // Return the task if we were constructed from one, otherwise manufacture one.  We don't
-            // cache the generated task into _task as it would end up changing both equality comparison
-            // and the hash code we generate in GetHashCode.
-            _task ?? Task.FromResult(_result);
-
-        /// <summary>Gets whether the <see cref="ValueTask{TResult}"/> represents a completed operation.</summary>
-        public bool IsCompleted => _task == null || _task.IsCompleted;
-
-        /// <summary>Gets whether the <see cref="ValueTask{TResult}"/> represents a successfully completed operation.</summary>
-        public bool IsCompletedSuccessfully => _task == null || _task.Status == TaskStatus.RanToCompletion;
-
-        /// <summary>Gets whether the <see cref="ValueTask{TResult}"/> represents a failed operation.</summary>
-        public bool IsFaulted => _task != null && _task.IsFaulted;
-
-        /// <summary>Gets whether the <see cref="ValueTask{TResult}"/> represents a canceled operation.</summary>
-        public bool IsCanceled => _task != null && _task.IsCanceled;
-
-        /// <summary>Gets the result.</summary>
-        public TResult Result => _task == null ? _result : _task.GetAwaiter().GetResult();
-
-        /// <summary>Gets an awaiter for this value.</summary>
-        public ValueTaskAwaiter<TResult> GetAwaiter() => new ValueTaskAwaiter<TResult>(this);
-
-        /// <summary>Configures an awaiter for this value.</summary>
-        /// <param name="continueOnCapturedContext">
-        /// true to attempt to marshal the continuation back to the captured context; otherwise, false.
-        /// </param>
-        public ConfiguredValueTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext) =>
-            new ConfiguredValueTaskAwaitable<TResult>(this, continueOnCapturedContext: continueOnCapturedContext);
-
-        /// <summary>Gets a string-representation of this <see cref="ValueTask{TResult}"/>.</summary>
-        public override string ToString()
-        {
-            if (_task != null)
-            {
-                return _task.Status == TaskStatus.RanToCompletion && _task.Result != null ?
-                    _task.Result.ToString() :
-                    string.Empty;
-            }
-            else
-            {
-                return _result != null ?
-                    _result.ToString() :
-                    string.Empty;
-            }
-        }
-
-        // TODO: Remove CreateAsyncMethodBuilder once the C# compiler relies on the AsyncBuilder attribute.
-
-        /// <summary>Creates a method builder for use with an async method.</summary>
-        /// <returns>The created builder.</returns>
-        [EditorBrowsable(EditorBrowsableState.Never)] // intended only for compiler consumption
-        public static AsyncValueTaskMethodBuilder<TResult> CreateAsyncMethodBuilder() => AsyncValueTaskMethodBuilder<TResult>.Create();
-    }
-}
diff --git a/src/libraries/System.Threading.Tasks.Extensions/src/System/ThrowHelper.cs b/src/libraries/System.Threading.Tasks.Extensions/src/System/ThrowHelper.cs
new file mode 100644 (file)
index 0000000..0757c61
--- /dev/null
@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+    internal static class ThrowHelper
+    {
+        internal static void ThrowArgumentNullException(ExceptionArgument argument) =>
+            throw GetArgumentNullException(argument);
+
+        private static ArgumentNullException GetArgumentNullException(ExceptionArgument argument) =>
+            new ArgumentNullException(GetArgumentName(argument));
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        private static string GetArgumentName(ExceptionArgument argument)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(ExceptionArgument), argument),
+                $"The enum value is not defined, please check the {nameof(ExceptionArgument)} enum.");
+
+            return argument.ToString();
+        }
+    }
+
+    internal enum ExceptionArgument
+    {
+        task
+    }
+}
index ab5b04a..9d8135b 100644 (file)
@@ -13,5 +13,8 @@
     <Compile Include="AsyncValueTaskMethodBuilderTests.cs" />
     <Compile Include="ValueTaskTests.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
 </Project>
\ No newline at end of file