diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
index 4e8ce691bec..f22b9d94bf6 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
@@ -35,10 +35,10 @@ public ConfiguredValueTaskAwaiter GetAwaiter() =>
/// Provides an awaiter for a .
[StructLayout(LayoutKind.Auto)]
- public struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, IConfiguredValueTaskAwaiter
+ public readonly struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, IConfiguredValueTaskAwaiter
{
/// The value being awaited.
- private ValueTask _value; // Methods are called on this; avoid making it readonly so as to avoid unnecessary copies
+ private readonly ValueTask _value;
/// The value to pass to ConfigureAwait.
internal readonly bool _continueOnCapturedContext;
@@ -74,7 +74,11 @@ public void UnsafeOnCompleted(Action continuation) =>
/// Gets the task underlying the incomplete .
/// This method is used when awaiting and IsCompleted returned false; thus we expect the value task to be wrapping a non-null task.
- (Task task, bool continueOnCapturedContext) IConfiguredValueTaskAwaiter.GetTask() => (_value.AsTaskExpectNonNull(), _continueOnCapturedContext);
+ Task IConfiguredValueTaskAwaiter.GetTask(out bool continueOnCapturedContext)
+ {
+ continueOnCapturedContext = _continueOnCapturedContext;
+ return _value.AsTaskExpectNonNull();
+ }
}
}
@@ -83,6 +87,6 @@ public void UnsafeOnCompleted(Action continuation) =>
///
internal interface IConfiguredValueTaskAwaiter
{
- (Task task, bool continueOnCapturedContext) GetTask();
+ Task GetTask(out bool continueOnCapturedContext);
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
index 7bc8b5cc7d3..3f212d8bf9b 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
@@ -8,10 +8,10 @@
namespace System.Runtime.CompilerServices
{
/// Provides an awaiter for a .
- public struct ValueTaskAwaiter : ICriticalNotifyCompletion, IValueTaskAwaiter
+ public readonly struct ValueTaskAwaiter : ICriticalNotifyCompletion, IValueTaskAwaiter
{
/// The value being awaited.
- private ValueTask _value; // Methods are called on this; avoid making it readonly so as to avoid unnecessary copies
+ private readonly ValueTask _value;
/// Initializes the awaiter.
/// The value to be awaited.
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
index de9b016328c..5edd8501b0c 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
@@ -3,7 +3,6 @@
// 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;
@@ -77,7 +76,7 @@ public ValueTask(Task task)
}
_task = task;
- _result = default(TResult);
+ _result = default;
}
/// Returns the hash code for this instance.
@@ -114,7 +113,12 @@ public Task 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 ?? AsyncTaskMethodBuilder.GetTaskForResult(_result);
+ _task ??
+#if netstandard
+ Task.FromResult(_result);
+#else
+ AsyncTaskMethodBuilder.GetTaskForResult(_result);
+#endif
internal Task AsTaskExpectNonNull() =>
// Return the task if we were constructed from one, otherwise manufacture one.
@@ -123,13 +127,24 @@ internal Task AsTaskExpectNonNull() =>
_task ?? GetTaskForResultNoInlining();
[MethodImpl(MethodImplOptions.NoInlining)]
- private Task GetTaskForResultNoInlining() => AsyncTaskMethodBuilder.GetTaskForResult(_result);
+ private Task GetTaskForResultNoInlining() =>
+#if netstandard
+ Task.FromResult(_result);
+#else
+ AsyncTaskMethodBuilder.GetTaskForResult(_result);
+#endif
/// Gets whether the represents a completed operation.
public bool IsCompleted => _task == null || _task.IsCompleted;
/// Gets whether the represents a successfully completed operation.
- public bool IsCompletedSuccessfully => _task == null || _task.IsCompletedSuccessfully;
+ public bool IsCompletedSuccessfully =>
+ _task == null ||
+#if netstandard
+ _task.Status == TaskStatus.RanToCompletion;
+#else
+ _task.IsCompletedSuccessfully;
+#endif
/// Gets whether the represents a failed operation.
public bool IsFaulted => _task != null && _task.IsFaulted;
@@ -153,26 +168,16 @@ public ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCaptu
/// Gets a string-representation of this .
public override string ToString()
{
- if (_task != null)
+ if (IsCompletedSuccessfully)
{
- return _task.IsCompletedSuccessfully && _task.Result != null ?
- _task.Result.ToString() :
- string.Empty;
+ TResult result = Result;
+ if (result != null)
+ {
+ return result.ToString();
+ }
}
- else
- {
- return _result != null ?
- _result.ToString() :
- string.Empty;
- }
- }
- // TODO https://github.com/dotnet/corefx/issues/22171:
- // Remove CreateAsyncMethodBuilder once the C# compiler relies on the AsyncBuilder attribute.
-
- /// Creates a method builder for use with an async method.
- /// The created builder.
- [EditorBrowsable(EditorBrowsableState.Never)] // intended only for compiler consumption
- public static AsyncValueTaskMethodBuilder CreateAsyncMethodBuilder() => AsyncValueTaskMethodBuilder.Create();
+ return string.Empty;
+ }
}
}