summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib/shared/System/Threading/Tasks
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-01-27 14:15:08 -0500
committerJan Kotas <jkotas@microsoft.com>2019-01-27 11:15:08 -0800
commit5d5d680e64769f4807d2e114b74e1304a58822d5 (patch)
tree25a69e8865cebc902b7b48daa58eea5e416a6397 /src/System.Private.CoreLib/shared/System/Threading/Tasks
parent307ec0b724c01aec62d93cf2046f6b671c3eeced (diff)
downloadcoreclr-5d5d680e64769f4807d2e114b74e1304a58822d5.tar.gz
coreclr-5d5d680e64769f4807d2e114b74e1304a58822d5.tar.bz2
coreclr-5d5d680e64769f4807d2e114b74e1304a58822d5.zip
Remove several uses of VoidTaskResult (#22238)
* Remove defunct netstandard code from ValueTask * Remove several uses of VoidTaskResult Currently TrySetResult/Canceled/Exception live on `Task<T>`. There's no reason `TrySetCanceled` and `TrySetException` need to live there, as they only access state from the base `Task`, and so can be moved down. `TrySetResult` needs the `TResult`, however in a variety of cases `Task<T>` is used with a `VoidTaskResult`, and for such cases we can just have a parameterless `TrySetResult()` on the base class as well, which can be used any time there is no `TResult` or when `default(TResult)` is the desired result. This lets us switch several cases where we were using `Task<VoidTaskResult>` to just be `Task`, which saves 8 bytes on the task instance on 64-bit. It also avoids an Interlocked.Exchange as part of the TrySetResult call. This primarily affects Task.Delay and the non-generic variants of Task.WhenAll, ValueTask.AsTask(), Task.FromCanceled, and Task.FromException.
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Threading/Tasks')
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs10
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs95
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs8
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs147
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs122
5 files changed, 163 insertions, 219 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
index 9adcdd6df9..e207a7421f 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
@@ -147,7 +147,7 @@ namespace System.Threading.Tasks
public Task Completion
{
// ValueLock not needed, but it's ok if it's held
- get { return EnsureCompletionStateInitialized().Task; }
+ get { return EnsureCompletionStateInitialized(); }
}
/// <summary>Gets the lazily-initialized completion state.</summary>
@@ -214,12 +214,12 @@ namespace System.Threading.Tasks
ThreadPool.QueueUserWorkItem(state =>
{
var localThis = (ConcurrentExclusiveSchedulerPair)state;
- Debug.Assert(!localThis.m_completionState.Task.IsCompleted, "Completion should only happen once.");
+ Debug.Assert(!localThis.m_completionState.IsCompleted, "Completion should only happen once.");
List<Exception> exceptions = localThis.m_completionState.m_exceptions;
bool success = (exceptions != null && exceptions.Count > 0) ?
localThis.m_completionState.TrySetException(exceptions) :
- localThis.m_completionState.TrySetResult(default);
+ localThis.m_completionState.TrySetResult();
Debug.Assert(success, "Expected to complete completion task.");
localThis.m_threadProcessingMode.Dispose();
@@ -479,7 +479,7 @@ namespace System.Threading.Tasks
/// the Completion.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
- private sealed class CompletionState : TaskCompletionSource<VoidTaskResult>
+ private sealed class CompletionState : Task
{
/// <summary>Whether the scheduler has had completion requested.</summary>
/// <remarks>This variable is not volatile, so to gurantee safe reading reads, Volatile.Read is used in TryExecuteTaskInline.</remarks>
@@ -741,7 +741,7 @@ namespace System.Threading.Tasks
get
{
// If our completion task is done, so are we.
- if (m_completionState != null && m_completionState.Task.IsCompleted) return ProcessingMode.Completed;
+ if (m_completionState != null && m_completionState.IsCompleted) return ProcessingMode.Completed;
// Otherwise, summarize our current state.
var mode = ProcessingMode.NotCurrentlyProcessing;
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs
index 5cc0b6737b..06eb1186ae 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs
@@ -386,6 +386,8 @@ namespace System.Threading.Tasks
{
Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");
+ bool returnValue = false;
+
// "Reserve" the completion for this task, while making sure that: (1) No prior reservation
// has been made, (2) The result has not already been set, (3) An exception has not previously
// been recorded, and (4) Cancellation has not been requested.
@@ -411,10 +413,10 @@ namespace System.Threading.Tasks
props.SetCompleted();
}
FinishContinuations();
- return true;
+ returnValue = true;
}
- return false;
+ return returnValue;
}
// Transitions the promise task into a successfully completed state with the specified result.
@@ -491,95 +493,6 @@ namespace System.Threading.Tasks
return m_result;
}
- // Allow multiple exceptions to be assigned to a promise-style task.
- // This is useful when a TaskCompletionSource<T> stands in as a proxy
- // for a "real" task (as we do in Unwrap(), ContinueWhenAny() and ContinueWhenAll())
- // and the "real" task ends up with multiple exceptions, which is possible when
- // a task has children.
- //
- // Called from TaskCompletionSource<T>.SetException(IEnumerable<Exception>).
- internal bool TrySetException(object exceptionObject)
- {
- Debug.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action");
-
- // TCS.{Try}SetException() should have checked for this
- Debug.Assert(exceptionObject != null, "Expected non-null exceptionObject argument");
-
- // Only accept these types.
- Debug.Assert(
- (exceptionObject is Exception) || (exceptionObject is IEnumerable<Exception>) ||
- (exceptionObject is ExceptionDispatchInfo) || (exceptionObject is IEnumerable<ExceptionDispatchInfo>),
- "Expected exceptionObject to be either Exception, ExceptionDispatchInfo, or IEnumerable<> of one of those");
-
- bool returnValue = false;
-
- // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
- // has been made, (2) The result has not already been set, (3) An exception has not previously
- // been recorded, and (4) Cancellation has not been requested.
- //
- // If the reservation is successful, then add the exception(s) and finish completion processing.
- //
- // The lazy initialization may not be strictly necessary, but I'd like to keep it here
- // anyway. Some downstream logic may depend upon an inflated m_contingentProperties.
- EnsureContingentPropertiesInitialized();
- if (AtomicStateUpdate(TASK_STATE_COMPLETION_RESERVED,
- TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED))
- {
- AddException(exceptionObject); // handles singleton exception or exception collection
- Finish(false);
- returnValue = true;
- }
-
- return returnValue;
- }
-
- // internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
- // If the tokenToRecord is not None, it will be stored onto the task.
- // This method is only valid for promise tasks.
- internal bool TrySetCanceled(CancellationToken tokenToRecord)
- {
- return TrySetCanceled(tokenToRecord, null);
- }
-
- // internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
- // If the tokenToRecord is not None, it will be stored onto the task.
- // If the OperationCanceledException is not null, it will be stored into the task's exception holder.
- // This method is only valid for promise tasks.
- internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException)
- {
- Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action");
-#if DEBUG
- var ceAsEdi = cancellationException as ExceptionDispatchInfo;
- Debug.Assert(
- cancellationException == null ||
- cancellationException is OperationCanceledException ||
- (ceAsEdi != null && ceAsEdi.SourceException is OperationCanceledException),
- "Expected null or an OperationCanceledException");
-#endif
-
- bool returnValue = false;
-
- // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
- // has been made, (2) The result has not already been set, (3) An exception has not previously
- // been recorded, and (4) Cancellation has not been requested.
- //
- // If the reservation is successful, then record the cancellation and finish completion processing.
- //
- // Note: I had to access static Task variables through Task<object>
- // instead of Task, because I have a property named Task and that
- // was confusing the compiler.
- if (AtomicStateUpdate(Task<object>.TASK_STATE_COMPLETION_RESERVED,
- Task<object>.TASK_STATE_COMPLETION_RESERVED | Task<object>.TASK_STATE_CANCELED |
- Task<object>.TASK_STATE_FAULTED | Task<object>.TASK_STATE_RAN_TO_COMPLETION))
- {
- RecordInternalCancellationRequest(tokenToRecord, cancellationException);
- CancellationCleanupLogic(); // perform cancellation cleanup actions
- returnValue = true;
- }
-
- return returnValue;
- }
-
/// <summary>
/// Provides access to factory methods for creating <see cref="Task{TResult}"/> instances.
/// </summary>
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs
index 0d8cdcb535..55fab9a5de 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs
@@ -800,7 +800,7 @@ namespace System.Threading.Tasks
Task.RemoveFromActiveTasks(promise);
// Make sure we don't leave promise "dangling".
- promise.TrySetResult(default);
+ promise.TrySetResult();
throw;
}
@@ -917,7 +917,7 @@ namespace System.Threading.Tasks
Task.RemoveFromActiveTasks(promise);
// Make sure we don't leave promise "dangling".
- promise.TrySetResult(default);
+ promise.TrySetResult();
throw;
}
@@ -1042,7 +1042,7 @@ namespace System.Threading.Tasks
Task.RemoveFromActiveTasks(promise);
// Make sure we don't leave promise "dangling".
- promise.TrySetResult(default);
+ promise.TrySetResult();
throw;
}
@@ -1175,7 +1175,7 @@ namespace System.Threading.Tasks
Task.RemoveFromActiveTasks(promise);
// Make sure we don't leave the promise "dangling".
- promise.TrySetResult(default);
+ promise.TrySetResult();
throw;
}
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
index 3f580c4bb0..2c19332555 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
@@ -3192,6 +3192,113 @@ namespace System.Threading.Tasks
m_stateFlags |= TASK_STATE_CANCELLATIONACKNOWLEDGED;
}
+ /// <summary>Completes a promise task as RanToCompletion.</summary>
+ /// <remarks>If this is a Task{T}, default(T) is the implied result.</remarks>
+ /// <returns>true if the task was transitioned to ran to completion; false if it was already completed.</returns>
+ internal bool TrySetResult()
+ {
+ Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");
+
+ if (AtomicStateUpdate(
+ TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION,
+ TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED))
+ {
+ ContingentProperties props = m_contingentProperties;
+ if (props != null)
+ {
+ NotifyParentIfPotentiallyAttachedTask();
+ props.SetCompleted();
+ }
+ FinishContinuations();
+ return true;
+ }
+
+ return false;
+ }
+
+ // Allow multiple exceptions to be assigned to a promise-style task.
+ // This is useful when a TaskCompletionSource<T> stands in as a proxy
+ // for a "real" task (as we do in Unwrap(), ContinueWhenAny() and ContinueWhenAll())
+ // and the "real" task ends up with multiple exceptions, which is possible when
+ // a task has children.
+ //
+ // Called from TaskCompletionSource<T>.SetException(IEnumerable<Exception>).
+ internal bool TrySetException(object exceptionObject)
+ {
+ Debug.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action");
+
+ // TCS.{Try}SetException() should have checked for this
+ Debug.Assert(exceptionObject != null, "Expected non-null exceptionObject argument");
+
+ // Only accept these types.
+ Debug.Assert(
+ (exceptionObject is Exception) || (exceptionObject is IEnumerable<Exception>) ||
+ (exceptionObject is ExceptionDispatchInfo) || (exceptionObject is IEnumerable<ExceptionDispatchInfo>),
+ "Expected exceptionObject to be either Exception, ExceptionDispatchInfo, or IEnumerable<> of one of those");
+
+ bool returnValue = false;
+
+ // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
+ // has been made, (2) The result has not already been set, (3) An exception has not previously
+ // been recorded, and (4) Cancellation has not been requested.
+ //
+ // If the reservation is successful, then add the exception(s) and finish completion processing.
+ //
+ // The lazy initialization may not be strictly necessary, but I'd like to keep it here
+ // anyway. Some downstream logic may depend upon an inflated m_contingentProperties.
+ EnsureContingentPropertiesInitialized();
+ if (AtomicStateUpdate(
+ TASK_STATE_COMPLETION_RESERVED,
+ TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED))
+ {
+ AddException(exceptionObject); // handles singleton exception or exception collection
+ Finish(false);
+ returnValue = true;
+ }
+
+ return returnValue;
+ }
+
+ // internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
+ // If the tokenToRecord is not None, it will be stored onto the task.
+ // This method is only valid for promise tasks.
+ internal bool TrySetCanceled(CancellationToken tokenToRecord)
+ {
+ return TrySetCanceled(tokenToRecord, null);
+ }
+
+ // internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
+ // If the tokenToRecord is not None, it will be stored onto the task.
+ // If the OperationCanceledException is not null, it will be stored into the task's exception holder.
+ // This method is only valid for promise tasks.
+ internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException)
+ {
+ Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action");
+ Debug.Assert(
+ cancellationException == null ||
+ cancellationException is OperationCanceledException ||
+ (cancellationException as ExceptionDispatchInfo)?.SourceException is OperationCanceledException,
+ "Expected null or an OperationCanceledException");
+
+ bool returnValue = false;
+
+ // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
+ // has been made, (2) The result has not already been set, (3) An exception has not previously
+ // been recorded, and (4) Cancellation has not been requested.
+ //
+ // If the reservation is successful, then record the cancellation and finish completion processing.
+ if (AtomicStateUpdate(
+ TASK_STATE_COMPLETION_RESERVED,
+ TASK_STATE_COMPLETION_RESERVED | TASK_STATE_CANCELED | TASK_STATE_FAULTED | TASK_STATE_RAN_TO_COMPLETION))
+ {
+ RecordInternalCancellationRequest(tokenToRecord, cancellationException);
+ CancellationCleanupLogic(); // perform cancellation cleanup actions
+ returnValue = true;
+ }
+
+ return returnValue;
+ }
+
//
// Continuation passing functionality (aka ContinueWith)
@@ -5054,7 +5161,12 @@ namespace System.Threading.Tasks
/// <returns>The faulted task.</returns>
public static Task FromException(Exception exception)
{
- return FromException<VoidTaskResult>(exception);
+ if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
+
+ var task = new Task();
+ bool succeeded = task.TrySetException(exception);
+ Debug.Assert(succeeded, "This should always succeed on a new task.");
+ return task;
}
/// <summary>Creates a <see cref="Task{TResult}"/> that's completed exceptionally with the specified exception.</summary>
@@ -5092,13 +5204,26 @@ namespace System.Threading.Tasks
return new Task<TResult>(true, default, TaskCreationOptions.None, cancellationToken);
}
+ /// <summary>Creates a <see cref="Task"/> that's completed due to cancellation with the specified exception.</summary>
+ /// <param name="exception">The exception with which to complete the task.</param>
+ /// <returns>The canceled task.</returns>
+ internal static Task FromCanceled(OperationCanceledException exception)
+ {
+ Debug.Assert(exception != null);
+
+ var task = new Task();
+ bool succeeded = task.TrySetCanceled(exception.CancellationToken, exception);
+ Debug.Assert(succeeded, "This should always succeed on a new task.");
+ return task;
+ }
+
/// <summary>Creates a <see cref="Task{TResult}"/> that's completed due to cancellation with the specified exception.</summary>
/// <typeparam name="TResult">The type of the result returned by the task.</typeparam>
/// <param name="exception">The exception with which to complete the task.</param>
/// <returns>The canceled task.</returns>
- internal static Task<TResult> FromCancellation<TResult>(OperationCanceledException exception)
+ internal static Task<TResult> FromCanceled<TResult>(OperationCanceledException exception)
{
- if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
+ Debug.Assert(exception != null);
var task = new Task<TResult>();
bool succeeded = task.TrySetCanceled(exception.CancellationToken, exception);
@@ -5389,10 +5514,9 @@ namespace System.Threading.Tasks
}
/// <summary>Task that also stores the completion closure and logic for Task.Delay implementation.</summary>
- private sealed class DelayPromise : Task<VoidTaskResult>
+ private sealed class DelayPromise : Task
{
internal DelayPromise(CancellationToken token)
- : base()
{
this.Token = token;
if (AsyncCausalityTracer.LoggingOn)
@@ -5423,7 +5547,7 @@ namespace System.Threading.Tasks
if (s_asyncDebuggingEnabled)
RemoveFromActiveTasks(this);
- setSucceeded = TrySetResult(default);
+ setSucceeded = TrySetResult();
}
// If we set the value, also clean up.
@@ -5555,10 +5679,10 @@ namespace System.Threading.Tasks
new WhenAllPromise(tasks);
}
- // A Task<VoidTaskResult> that gets completed when all of its constituent tasks complete.
+ // A Task that gets completed when all of its constituent tasks complete.
// Completion logic will analyze the antecedents in order to choose completion status.
// This type allows us to replace this logic:
- // Task<VoidTaskResult> promise = new Task<VoidTaskResult>(...);
+ // Task promise = new Task(...);
// Action<Task> completionAction = delegate { <completion logic>};
// TaskFactory.CommonCWAllLogic(tasksCopy).AddCompletionAction(completionAction);
// return promise;
@@ -5567,7 +5691,7 @@ namespace System.Threading.Tasks
// which saves a couple of allocations and enables debugger notification specialization.
//
// Used in InternalWhenAll(Task[])
- private sealed class WhenAllPromise : Task<VoidTaskResult>, ITaskCompletionAction
+ private sealed class WhenAllPromise : Task, ITaskCompletionAction
{
/// <summary>
/// Stores all of the constituent tasks. Tasks clear themselves out of this
@@ -5577,8 +5701,7 @@ namespace System.Threading.Tasks
/// <summary>The number of tasks remaining to complete.</summary>
private int m_count;
- internal WhenAllPromise(Task[] tasks) :
- base()
+ internal WhenAllPromise(Task[] tasks)
{
Debug.Assert(tasks != null, "Expected a non-null task array");
Debug.Assert(tasks.Length > 0, "Expected a non-zero length task array");
@@ -5656,7 +5779,7 @@ namespace System.Threading.Tasks
if (s_asyncDebuggingEnabled)
RemoveFromActiveTasks(this);
- TrySetResult(default);
+ TrySetResult();
}
}
Debug.Assert(m_count >= 0, "Count should never go below 0");
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 4d6a759605..256d4d71a2 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
@@ -7,10 +7,7 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks.Sources;
-
-#if !netstandard
using Internal.Runtime.CompilerServices;
-#endif
namespace System.Threading.Tasks
{
@@ -60,19 +57,10 @@ namespace System.Threading.Tasks
public readonly struct ValueTask : IEquatable<ValueTask>
{
/// <summary>A task canceled using `new CancellationToken(true)`.</summary>
- private static readonly Task s_canceledTask =
-#if netstandard
- Task.Delay(Timeout.Infinite, new CancellationToken(canceled: true));
-#else
- Task.FromCanceled(new CancellationToken(canceled: true));
-#endif
+ private static readonly Task s_canceledTask = Task.FromCanceled(new CancellationToken(canceled: true));
+
/// <summary>A successfully completed task.</summary>
- internal static Task CompletedTask
-#if netstandard
- { get; } = Task.Delay(0);
-#else
- => Task.CompletedTask;
-#endif
+ internal static Task CompletedTask => Task.CompletedTask;
/// <summary>null if representing a successful synchronous completion, otherwise a <see cref="Task"/> or a <see cref="IValueTaskSource"/>.</summary>
internal readonly object _obj;
@@ -190,45 +178,27 @@ namespace System.Threading.Tasks
{
if (status == ValueTaskSourceStatus.Canceled)
{
-#if !netstandard
if (exc is OperationCanceledException oce)
{
- var task = new Task<VoidTaskResult>();
+ var task = new Task();
task.TrySetCanceled(oce.CancellationToken, oce);
return task;
}
-#endif
+
return s_canceledTask;
}
else
{
-#if netstandard
- var tcs = new TaskCompletionSource<bool>();
- tcs.TrySetException(exc);
- return tcs.Task;
-#else
return Task.FromException(exc);
-#endif
}
}
}
- var m = new ValueTaskSourceAsTask(t, _token);
- return
-#if netstandard
- m.Task;
-#else
- m;
-#endif
+ return new ValueTaskSourceAsTask(t, _token);
}
/// <summary>Type used to create a <see cref="Task"/> to represent a <see cref="IValueTaskSource"/>.</summary>
- private sealed class ValueTaskSourceAsTask :
-#if netstandard
- TaskCompletionSource<bool>
-#else
- Task<VoidTaskResult>
-#endif
+ private sealed class ValueTaskSourceAsTask : Task
{
private static readonly Action<object> s_completionAction = state =>
{
@@ -247,15 +217,12 @@ namespace System.Threading.Tasks
try
{
source.GetResult(vtst._token);
- vtst.TrySetResult(default);
+ vtst.TrySetResult();
}
catch (Exception exc)
{
if (status == ValueTaskSourceStatus.Canceled)
{
-#if netstandard
- vtst.TrySetCanceled();
-#else
if (exc is OperationCanceledException oce)
{
vtst.TrySetCanceled(oce.CancellationToken, oce);
@@ -264,7 +231,6 @@ namespace System.Threading.Tasks
{
vtst.TrySetCanceled(new CancellationToken(true));
}
-#endif
}
else
{
@@ -325,12 +291,7 @@ namespace System.Threading.Tasks
if (obj is Task t)
{
- return
-#if netstandard
- t.Status == TaskStatus.RanToCompletion;
-#else
- t.IsCompletedSuccessfully;
-#endif
+ return t.IsCompletedSuccessfully;
}
return Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded;
@@ -398,11 +359,7 @@ namespace System.Threading.Tasks
{
if (obj is Task t)
{
-#if netstandard
- t.GetAwaiter().GetResult();
-#else
TaskAwaiter.ValidateEnd(t);
-#endif
}
else
{
@@ -569,12 +526,7 @@ namespace System.Threading.Tasks
if (obj == null)
{
- return
-#if netstandard
- Task.FromResult(_result);
-#else
- AsyncTaskMethodBuilder<TResult>.GetTaskForResult(_result);
-#endif
+ return AsyncTaskMethodBuilder<TResult>.GetTaskForResult(_result);
}
if (obj is Task<TResult> t)
@@ -602,12 +554,7 @@ namespace System.Threading.Tasks
{
// Get the result of the operation and return a task for it.
// If any exception occurred, propagate it
- return
-#if netstandard
- Task.FromResult(t.GetResult(_token));
-#else
- AsyncTaskMethodBuilder<TResult>.GetTaskForResult(t.GetResult(_token));
-#endif
+ return AsyncTaskMethodBuilder<TResult>.GetTaskForResult(t.GetResult(_token));
// If status is Faulted or Canceled, GetResult should throw. But
// we can't guarantee every implementation will do the "right thing".
@@ -618,59 +565,33 @@ namespace System.Threading.Tasks
{
if (status == ValueTaskSourceStatus.Canceled)
{
-#if !netstandard
if (exc is OperationCanceledException oce)
{
var task = new Task<TResult>();
task.TrySetCanceled(oce.CancellationToken, oce);
return task;
}
-#endif
Task<TResult> canceledTask = s_canceledTask;
if (canceledTask == null)
{
-#if netstandard
- var tcs = new TaskCompletionSource<TResult>();
- tcs.TrySetCanceled();
- canceledTask = tcs.Task;
-#else
- canceledTask = Task.FromCanceled<TResult>(new CancellationToken(true));
-#endif
// Benign race condition to initialize cached task, as identity doesn't matter.
- s_canceledTask = canceledTask;
+ s_canceledTask = Task.FromCanceled<TResult>(new CancellationToken(true));
}
return canceledTask;
}
else
{
-#if netstandard
- var tcs = new TaskCompletionSource<TResult>();
- tcs.TrySetException(exc);
- return tcs.Task;
-#else
return Task.FromException<TResult>(exc);
-#endif
}
}
}
- var m = new ValueTaskSourceAsTask(t, _token);
- return
-#if netstandard
- m.Task;
-#else
- m;
-#endif
+ return new ValueTaskSourceAsTask(t, _token);
}
/// <summary>Type used to create a <see cref="Task{TResult}"/> to represent a <see cref="IValueTaskSource{TResult}"/>.</summary>
- private sealed class ValueTaskSourceAsTask :
-#if netstandard
- TaskCompletionSource<TResult>
-#else
- Task<TResult>
-#endif
+ private sealed class ValueTaskSourceAsTask : Task<TResult>
{
private static readonly Action<object> s_completionAction = state =>
{
@@ -694,9 +615,6 @@ namespace System.Threading.Tasks
{
if (status == ValueTaskSourceStatus.Canceled)
{
-#if netstandard
- vtst.TrySetCanceled();
-#else
if (exc is OperationCanceledException oce)
{
vtst.TrySetCanceled(oce.CancellationToken, oce);
@@ -705,7 +623,6 @@ namespace System.Threading.Tasks
{
vtst.TrySetCanceled(new CancellationToken(true));
}
-#endif
}
else
{
@@ -766,12 +683,7 @@ namespace System.Threading.Tasks
if (obj is Task<TResult> t)
{
- return
-#if netstandard
- t.Status == TaskStatus.RanToCompletion;
-#else
- t.IsCompletedSuccessfully;
-#endif
+ return t.IsCompletedSuccessfully;
}
return Unsafe.As<IValueTaskSource<TResult>>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded;
@@ -843,12 +755,8 @@ namespace System.Threading.Tasks
if (obj is Task<TResult> t)
{
-#if netstandard
- return t.GetAwaiter().GetResult();
-#else
TaskAwaiter.ValidateEnd(t);
return t.ResultOnSuccess;
-#endif
}
return Unsafe.As<IValueTaskSource<TResult>>(obj).GetResult(_token);