summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib/shared/System/Threading/Tasks
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-05-28 06:04:13 -0400
committerGitHub <noreply@github.com>2019-05-28 06:04:13 -0400
commit4a1275434fff99206f2a28f5f0e87f124069eb7f (patch)
tree4e5c7667e29c969179a965048f2452f4d4bad3ad /src/System.Private.CoreLib/shared/System/Threading/Tasks
parentbb75edbac9c40034b6683c17d86057ee9bf4192d (diff)
downloadcoreclr-4a1275434fff99206f2a28f5f0e87f124069eb7f.tar.gz
coreclr-4a1275434fff99206f2a28f5f0e87f124069eb7f.tar.bz2
coreclr-4a1275434fff99206f2a28f5f0e87f124069eb7f.zip
Add and apply nullable attributes (#24679)
* Add and apply nullable attributes * Adapt to API review decisions * Address PR feedback
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.cs50
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs91
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs15
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs4
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs11
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs96
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs8
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs16
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs7
12 files changed, 163 insertions, 149 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 9065ae1666..50014bf597 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
@@ -152,7 +152,11 @@ namespace System.Threading.Tasks
private CompletionState EnsureCompletionStateInitialized()
{
// ValueLock not needed, but it's ok if it's held
- return LazyInitializer.EnsureInitialized<CompletionState>(ref m_completionState!, () => new CompletionState()); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+#pragma warning disable CS8634 // TODO-NULLABLE: Remove warning disable when nullable attributes are respected
+#pragma warning disable CS8603 // TODO-NULLABLE: Remove warning disable when nullable attributes are respected
+ return LazyInitializer.EnsureInitialized(ref m_completionState!, () => new CompletionState());
+#pragma warning restore CS8603
+#pragma warning restore CS8634
}
/// <summary>Gets whether completion has been requested.</summary>
@@ -297,7 +301,7 @@ namespace System.Threading.Tasks
{
try
{
- processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair!).ProcessExclusiveTasks(), this, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair!).ProcessExclusiveTasks(), this,
default, GetCreationOptionsForTask(fairly));
processingTask.Start(m_underlyingTaskScheduler);
// When we call Start, if the underlying scheduler throws in QueueTask, TPL will fault the task and rethrow
@@ -327,7 +331,7 @@ namespace System.Threading.Tasks
{
try
{
- processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair!).ProcessConcurrentTasks(), this, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair!).ProcessConcurrentTasks(), this,
default, GetCreationOptionsForTask(fairly));
processingTask.Start(m_underlyingTaskScheduler); // See above logic for why we use new + Start rather than StartNew
}
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 c82372c000..1a7899d97c 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs
@@ -12,6 +12,7 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
@@ -60,7 +61,8 @@ namespace System.Threading.Tasks
[DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription}")]
public class Task<TResult> : Task
{
- internal TResult m_result = default!; // The value itself, if set. // TODO-NULLABLE-GENERIC
+ // The value itself, if set.
+ [MaybeNull] internal TResult m_result = default!; // TODO-NULLABLE: Remove ! when nullable attributes are respected
private static readonly TaskFactory<TResult> s_Factory = new TaskFactory<TResult>();
@@ -95,7 +97,7 @@ namespace System.Threading.Tasks
m_result = result;
}
- internal Task(bool canceled, TResult result, TaskCreationOptions creationOptions, CancellationToken ct)
+ internal Task(bool canceled, [AllowNull] TResult result, TaskCreationOptions creationOptions, CancellationToken ct)
: base(canceled, creationOptions, ct)
{
if (!canceled)
@@ -209,7 +211,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ArgumentException">
/// The <paramref name="function"/> argument is null.
/// </exception>
- public Task(Func<object?, TResult> function, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Func<object?, TResult> function, object? state)
: this(function, state, null, default,
TaskCreationOptions.None, InternalTaskOptions.None, null)
{
@@ -230,7 +232,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task(Func<object?, TResult> function, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Func<object?, TResult> function, object? state, CancellationToken cancellationToken)
: this(function, state, null, cancellationToken,
TaskCreationOptions.None, InternalTaskOptions.None, null)
{
@@ -255,7 +257,7 @@ namespace System.Threading.Tasks
/// The <paramref name="creationOptions"/> argument specifies an invalid value for <see
/// cref="T:System.Threading.Tasks.TaskCreationOptions"/>.
/// </exception>
- public Task(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions)
: this(function, state, Task.InternalCurrentIfAttached(creationOptions), default,
creationOptions, InternalTaskOptions.None, null)
{
@@ -285,7 +287,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
: this(function, state, Task.InternalCurrentIfAttached(creationOptions), cancellationToken,
creationOptions, InternalTaskOptions.None, null)
{
@@ -337,7 +339,7 @@ namespace System.Threading.Tasks
}
// Create and schedule the future.
- Task<TResult> f = new Task<TResult>(function!, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ Task<TResult> f = new Task<TResult>(function!, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
f.ScheduleAndStart(false);
return f;
@@ -357,7 +359,7 @@ namespace System.Threading.Tasks
}
// Create and schedule the future.
- Task<TResult> f = new Task<TResult>(function!, state, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ Task<TResult> f = new Task<TResult>(function!, state, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
f.ScheduleAndStart(false);
return f;
@@ -383,7 +385,7 @@ namespace System.Threading.Tasks
// internal helper function breaks out logic used by TaskCompletionSource
- internal bool TrySetResult(TResult result)
+ internal bool TrySetResult([AllowNull] TResult result)
{
Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");
@@ -725,13 +727,13 @@ namespace System.Threading.Tasks
out internalOptions);
Task continuationTask = new ContinuationTaskFromResultTask<TResult>(
- this, continuationAction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationAction!, null, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationTask;
}
@@ -756,7 +758,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="continuationAction"/> argument is null.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state)
{
return ContinueWith(continuationAction, state, TaskScheduler.Current, default, TaskContinuationOptions.None);
}
@@ -783,7 +785,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, CancellationToken cancellationToken)
{
return ContinueWith(continuationAction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None);
}
@@ -812,7 +814,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="scheduler"/> argument is null.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskScheduler scheduler) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskScheduler scheduler)
{
return ContinueWith(continuationAction, state, scheduler, default, TaskContinuationOptions.None);
}
@@ -846,7 +848,7 @@ namespace System.Threading.Tasks
/// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
/// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskContinuationOptions continuationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskContinuationOptions continuationOptions)
{
return ContinueWith(continuationAction, state, TaskScheduler.Current, default, continuationOptions);
}
@@ -890,14 +892,14 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
return ContinueWith(continuationAction, state, scheduler, cancellationToken, continuationOptions);
}
// Same as the above overload, only with a stack mark.
- internal Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskScheduler scheduler, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ internal Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskScheduler scheduler, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions)
{
if (continuationAction == null)
@@ -918,13 +920,13 @@ namespace System.Threading.Tasks
out internalOptions);
Task continuationTask = new ContinuationTaskFromResultTask<TResult>(
- this, continuationAction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationAction!, state, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationTask;
}
@@ -1134,13 +1136,13 @@ namespace System.Threading.Tasks
out internalOptions);
Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>(
- this, continuationFunction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationFunction!, null, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationFuture, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationFuture, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationFuture;
}
@@ -1357,13 +1359,13 @@ namespace System.Threading.Tasks
out internalOptions);
Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>(
- this, continuationFunction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationFunction!, state, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationFuture, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationFuture, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationFuture;
}
@@ -1384,7 +1386,7 @@ namespace System.Threading.Tasks
m_task = task;
}
- public TResult Result { get { return m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default!; } } // TODO-NULLABLE-GENERIC
+ [MaybeNull] public TResult Result { get { return m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default!; } }
public object? AsyncState { get { return m_task.AsyncState; } }
public TaskCreationOptions CreationOptions { get { return m_task.CreationOptions; } }
public Exception? Exception { get { return m_task.Exception; } }
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 e8be5bd091..139e32fda3 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
namespace System.Threading.Tasks
{
@@ -376,7 +377,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew(Func<object?, TResult> function, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew(Func<object?, TResult> function, object? state)
{
Task? currTask = Task.InternalCurrent;
return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
@@ -405,7 +406,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew(Func<object?, TResult> function, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew(Func<object?, TResult> function, object? state, CancellationToken cancellationToken)
{
Task? currTask = Task.InternalCurrent;
return Task<TResult>.StartNew(currTask, function, state, cancellationToken,
@@ -436,7 +437,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions)
{
Task? currTask = Task.InternalCurrent;
return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
@@ -478,7 +479,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
return Task<TResult>.StartNew(Task.InternalCurrentIfAttached(creationOptions), function, state, cancellationToken,
creationOptions, InternalTaskOptions.None, scheduler);
@@ -500,7 +501,7 @@ namespace System.Threading.Tasks
Exception? ex = null;
OperationCanceledException? oce = null;
- TResult result = default!; // TODO-NULLABLE-GENERIC
+ TResult result = default!;
try
{
@@ -671,9 +672,9 @@ namespace System.Threading.Tasks
if (Task.s_asyncDebuggingEnabled)
Task.AddToActiveTasks(t);
- if (asyncResult!.IsCompleted) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ if (asyncResult!.IsCompleted) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
- try { t.InternalRunSynchronously(scheduler!, waitForCompletion: false); } // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ try { t.InternalRunSynchronously(scheduler!, waitForCompletion: false); } // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
catch (Exception e) { promise.TrySetException(e); } // catch and log any scheduler exceptions
}
else
@@ -682,7 +683,7 @@ namespace System.Threading.Tasks
asyncResult.AsyncWaitHandle,
delegate
{
- try { t.InternalRunSynchronously(scheduler!, waitForCompletion: false); } // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ try { t.InternalRunSynchronously(scheduler!, waitForCompletion: false); } // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
catch (Exception e) { promise.TrySetException(e); } // catch and log any scheduler exceptions
},
null,
@@ -712,7 +713,7 @@ namespace System.Threading.Tasks
/// </remarks>
public Task<TResult> FromAsync(
Func<AsyncCallback, object?, IAsyncResult> beginMethod,
- Func<IAsyncResult, TResult> endMethod, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ Func<IAsyncResult, TResult> endMethod, object? state)
{
return FromAsyncImpl(beginMethod, endMethod, null, state, m_defaultCreationOptions);
}
@@ -741,7 +742,7 @@ namespace System.Threading.Tasks
/// </remarks>
public Task<TResult> FromAsync(
Func<AsyncCallback, object?, IAsyncResult> beginMethod,
- Func<IAsyncResult, TResult> endMethod, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ Func<IAsyncResult, TResult> endMethod, object? state, TaskCreationOptions creationOptions)
{
return FromAsyncImpl(beginMethod, endMethod, null, state, creationOptions);
}
@@ -765,7 +766,7 @@ namespace System.Threading.Tasks
Task<TResult> promise = new Task<TResult>(state, creationOptions);
if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (Task.s_asyncDebuggingEnabled)
Task.AddToActiveTasks(promise);
@@ -773,7 +774,7 @@ namespace System.Threading.Tasks
try
{
//if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod!(iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ var asyncResult = beginMethod!(iar => // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
@@ -824,7 +825,7 @@ namespace System.Threading.Tasks
public Task<TResult> FromAsync<TArg1>(
Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod,
Func<IAsyncResult, TResult> endMethod,
- TArg1 arg1, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ TArg1 arg1, object? state)
{
return FromAsyncImpl(beginMethod, endMethod, null, arg1, state, m_defaultCreationOptions);
}
@@ -858,7 +859,7 @@ namespace System.Threading.Tasks
public Task<TResult> FromAsync<TArg1>(
Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod,
Func<IAsyncResult, TResult> endMethod,
- TArg1 arg1, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ TArg1 arg1, object? state, TaskCreationOptions creationOptions)
{
return FromAsyncImpl(beginMethod, endMethod, null, arg1, state, creationOptions);
}
@@ -882,7 +883,7 @@ namespace System.Threading.Tasks
Task<TResult> promise = new Task<TResult>(state, creationOptions);
if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (Task.s_asyncDebuggingEnabled)
Task.AddToActiveTasks(promise);
@@ -890,7 +891,7 @@ namespace System.Threading.Tasks
try
{
//if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod!(arg1, iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ var asyncResult = beginMethod!(arg1, iar => // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
@@ -945,7 +946,7 @@ namespace System.Threading.Tasks
public Task<TResult> FromAsync<TArg1, TArg2>(
Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod,
Func<IAsyncResult, TResult> endMethod,
- TArg1 arg1, TArg2 arg2, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ TArg1 arg1, TArg2 arg2, object? state)
{
return FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, m_defaultCreationOptions);
}
@@ -983,7 +984,7 @@ namespace System.Threading.Tasks
public Task<TResult> FromAsync<TArg1, TArg2>(
Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod,
Func<IAsyncResult, TResult> endMethod,
- TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions)
{
return FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, creationOptions);
}
@@ -992,7 +993,7 @@ namespace System.Threading.Tasks
// method can access the logic w/o declaring a TaskFactory<TResult> instance.
internal static Task<TResult> FromAsyncImpl<TArg1, TArg2>(Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod,
Func<IAsyncResult, TResult>? endFunction, Action<IAsyncResult>? endAction,
- TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions)
{
if (beginMethod == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.beginMethod);
@@ -1007,7 +1008,7 @@ namespace System.Threading.Tasks
Task<TResult> promise = new Task<TResult>(state, creationOptions);
if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (Task.s_asyncDebuggingEnabled)
Task.AddToActiveTasks(promise);
@@ -1015,7 +1016,7 @@ namespace System.Threading.Tasks
try
{
//if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod!(arg1, arg2, iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ var asyncResult = beginMethod!(arg1, arg2, iar => // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
@@ -1140,7 +1141,7 @@ namespace System.Threading.Tasks
Task<TResult> promise = new Task<TResult>(state, creationOptions);
if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (Task.s_asyncDebuggingEnabled)
Task.AddToActiveTasks(promise);
@@ -1148,7 +1149,7 @@ namespace System.Threading.Tasks
try
{
//if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod!(arg1, arg2, arg3, iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ var asyncResult = beginMethod!(arg1, arg2, arg3, iar => // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
@@ -1228,7 +1229,7 @@ namespace System.Threading.Tasks
internal static readonly AsyncCallback s_completeFromAsyncResult = CompleteFromAsyncResult;
/// <summary>A reference to the object on which the begin/end methods are invoked.</summary>
- private TInstance m_thisRef;
+ [AllowNull, MaybeNull] private TInstance m_thisRef;
/// <summary>The end method.</summary>
private Func<TInstance, IAsyncResult, TResult>? m_endMethod;
@@ -1253,13 +1254,13 @@ namespace System.Threading.Tasks
// Validate argument
if (asyncResult == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.asyncResult);
- var promise = asyncResult!.AsyncState as FromAsyncTrimPromise<TInstance>; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ var promise = asyncResult!.AsyncState as FromAsyncTrimPromise<TInstance>; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (promise == null) ThrowHelper.ThrowArgumentException(ExceptionResource.InvalidOperation_WrongAsyncResultOrEndCalledMultiple, ExceptionArgument.asyncResult);
// Grab the relevant state and then null it out so that the task doesn't hold onto the state unnecessarily
- var thisRef = promise!.m_thisRef; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ var thisRef = promise!.m_thisRef; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
var endMethod = promise.m_endMethod;
- promise.m_thisRef = default!; // TODO-NULLABLE-GENERIC
+ promise.m_thisRef = default!; // TODO-NULLABLE: Remove ! when nullable attributes are respected
promise.m_endMethod = null;
if (endMethod == null) ThrowHelper.ThrowArgumentException(ExceptionResource.InvalidOperation_WrongAsyncResultOrEndCalledMultiple, ExceptionArgument.asyncResult);
@@ -1267,7 +1268,7 @@ namespace System.Threading.Tasks
// we'll instead complete the promise at the call site.
if (!asyncResult.CompletedSynchronously)
{
- promise.Complete(thisRef, endMethod!, asyncResult, requiresSynchronization: true); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ promise.Complete(thisRef, endMethod!, asyncResult, requiresSynchronization: true); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
}
@@ -1322,7 +1323,7 @@ namespace System.Threading.Tasks
{
TaskCreationOptions tco;
Task.CreationOptionsFromContinuationOptions(continuationOptions, out tco, out _);
- return new Task<TResult>(true, default!, tco, ct); // TODO-NULLABLE-GENERIC
+ return new Task<TResult>(true, default!, tco, ct); // TODO-NULLABLE: Remove ! when nullable attributes are respected
}
//
@@ -1610,7 +1611,7 @@ namespace System.Threading.Tasks
if (scheduler == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
// Check tasks array and make defensive copy
- Task<TAntecedentResult>[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy<TAntecedentResult>(tasks!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ Task<TAntecedentResult>[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy<TAntecedentResult>(tasks!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
// Bail early if cancellation has been requested.
if (cancellationToken.IsCancellationRequested
@@ -1629,7 +1630,7 @@ namespace System.Threading.Tasks
return starter.ContinueWith<TResult>(
// use a cached delegate
GenericDelegateCache<TAntecedentResult, TResult>.CWAllFuncDelegate,
- continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
else
{
@@ -1638,7 +1639,7 @@ namespace System.Threading.Tasks
return starter.ContinueWith<TResult>(
// use a cached delegate
GenericDelegateCache<TAntecedentResult, TResult>.CWAllActionDelegate,
- continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
}
@@ -1656,7 +1657,7 @@ namespace System.Threading.Tasks
if (scheduler == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
// Check tasks array and make defensive copy
- Task[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy(tasks!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ Task[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy(tasks!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
// Bail early if cancellation has been requested.
if (cancellationToken.IsCancellationRequested
@@ -1682,7 +1683,7 @@ namespace System.Threading.Tasks
Debug.Assert(state is Func<Task[], TResult>);
return ((Func<Task[], TResult>)state)(completedTasks.Result);
},
- continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
else
{
@@ -1695,9 +1696,9 @@ namespace System.Threading.Tasks
{
completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary();
Debug.Assert(state is Action<Task[]>);
- ((Action<Task[]>)state)(completedTasks.Result); return default!; // TODO-NULLABLE-GENERIC
+ ((Action<Task[]>)state)(completedTasks.Result); return default!;
},
- continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
}
@@ -1980,7 +1981,7 @@ namespace System.Threading.Tasks
// check arguments
TaskFactory.CheckMultiTaskContinuationOptions(continuationOptions);
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
- if (tasks!.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ if (tasks!.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
//ArgumentNullException of continuationFunction or continuationAction is checked by the caller
Debug.Assert((continuationFunction != null) != (continuationAction != null), "Expected exactly one of endFunction/endAction to be non-null");
@@ -2008,7 +2009,7 @@ namespace System.Threading.Tasks
Debug.Assert(state is Func<Task, TResult>);
return ((Func<Task, TResult>)state)(completedTask.Result);
},
- continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
else
{
@@ -2020,9 +2021,9 @@ namespace System.Threading.Tasks
{
Debug.Assert(state is Action<Task>);
((Action<Task>)state)(completedTask.Result);
- return default!; // TODO-NULLABLE-GENERIC
+ return default!;
},
- continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
}
@@ -2036,7 +2037,7 @@ namespace System.Threading.Tasks
// check arguments
TaskFactory.CheckMultiTaskContinuationOptions(continuationOptions);
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
- if (tasks!.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ if (tasks!.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
//ArgumentNullException of continuationFunction or continuationAction is checked by the caller
Debug.Assert((continuationFunction != null) != (continuationAction != null), "Expected exactly one of endFunction/endAction to be non-null");
if (scheduler == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
@@ -2058,7 +2059,7 @@ namespace System.Threading.Tasks
return starter.ContinueWith<TResult>(
// Use a cached delegate
GenericDelegateCache<TAntecedentResult, TResult>.CWAnyFuncDelegate,
- continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
else
{
@@ -2066,7 +2067,7 @@ namespace System.Threading.Tasks
return starter.ContinueWith<TResult>(
// Use a cached delegate
GenericDelegateCache<TAntecedentResult, TResult>.CWAnyActionDelegate,
- continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
}
}
@@ -2094,7 +2095,7 @@ namespace System.Threading.Tasks
var action = (Action<Task<TAntecedentResult>>)state;
var arg = (Task<TAntecedentResult>)wrappedWinner.Result;
action(arg);
- return default!; // TODO-NULLABLE-GENERIC
+ return default!;
};
// ContinueWith delegate for TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(non-null continuationFunction)
@@ -2115,7 +2116,7 @@ namespace System.Threading.Tasks
Debug.Assert(state is Action<Task<TAntecedentResult>[]>);
var action = (Action<Task<TAntecedentResult>[]>)state;
action(wrappedAntecedents.Result);
- return default!; // TODO-NULLABLE-GENERIC
+ return default!;
};
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs
index 157ad5d666..9fa82edb6e 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs
@@ -25,6 +25,7 @@ using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace System.Threading.Tasks
@@ -42,7 +43,7 @@ namespace System.Threading.Tasks
/// <param name="result">The dequeued item.</param>
/// <returns>true if an item could be dequeued; otherwise, false.</returns>
/// <remarks>This method is meant to be thread-safe subject to the particular nature of the implementation.</remarks>
- bool TryDequeue(out T result);
+ bool TryDequeue([MaybeNullWhen(false)] out T result);
/// <summary>Gets whether the collection is currently empty.</summary>
/// <remarks>This method may or may not be thread-safe.</remarks>
@@ -67,7 +68,7 @@ namespace System.Threading.Tasks
/// <summary>Attempts to dequeue an item from the queue.</summary>
/// <param name="result">The dequeued item.</param>
/// <returns>true if an item could be dequeued; otherwise, false.</returns>
- bool IProducerConsumerQueue<T>.TryDequeue(out T result) { return base.TryDequeue(out result); }
+ bool IProducerConsumerQueue<T>.TryDequeue([MaybeNullWhen(false)] out T result) { return base.TryDequeue(out result); }
/// <summary>Gets whether the collection is currently empty.</summary>
bool IProducerConsumerQueue<T>.IsEmpty { get { return base.IsEmpty; } }
@@ -194,7 +195,7 @@ namespace System.Threading.Tasks
/// <summary>Attempts to dequeue an item from the queue.</summary>
/// <param name="result">The dequeued item.</param>
/// <returns>true if an item could be dequeued; otherwise, false.</returns>
- public bool TryDequeue(out T result)
+ public bool TryDequeue([MaybeNullWhen(false)] out T result)
{
Segment segment = m_head;
var array = segment.m_array;
@@ -204,7 +205,7 @@ namespace System.Threading.Tasks
if (first != segment.m_state.m_lastCopy)
{
result = array[first];
- array[first] = default!; // Clear the slot to release the element // TODO-NULLABLE-GENERIC
+ array[first] = default!; // Clear the slot to release the element
segment.m_state.m_first = (first + 1) & (array.Length - 1);
return true;
}
@@ -217,7 +218,7 @@ namespace System.Threading.Tasks
/// <param name="segment">The segment from which the item was dequeued.</param>
/// <param name="result">The dequeued item.</param>
/// <returns>true if an item could be dequeued; otherwise, false.</returns>
- private bool TryDequeueSlow(ref Segment segment, ref T[] array, out T result)
+ private bool TryDequeueSlow(ref Segment segment, ref T[] array, [MaybeNullWhen(false)] out T result)
{
Debug.Assert(segment != null, "Expected a non-null segment.");
Debug.Assert(array != null, "Expected a non-null item array.");
@@ -239,12 +240,12 @@ namespace System.Threading.Tasks
if (first == segment.m_state.m_last)
{
- result = default!; // TODO-NULLABLE-GENERIC
+ result = default!;
return false;
}
result = array[first];
- array[first] = default!; // Clear the slot to release the element // TODO-NULLABLE-GENERIC
+ array[first] = default!; // Clear the slot to release the element
segment.m_state.m_first = (first + 1) & (segment.m_array.Length - 1);
segment.m_state.m_lastCopy = segment.m_state.m_last; // Refresh m_lastCopy to ensure that m_first has not passed m_lastCopy
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs
index 8f460370c0..5f071b2749 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs
@@ -53,7 +53,7 @@ namespace System.Threading.Tasks.Sources
/// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param>
/// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param>
/// <param name="flags">The flags describing the behavior of the continuation.</param>
- void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags);
/// <summary>Gets the result of the <see cref="IValueTaskSource"/>.</summary>
/// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param>
@@ -73,7 +73,7 @@ namespace System.Threading.Tasks.Sources
/// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param>
/// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param>
/// <param name="flags">The flags describing the behavior of the continuation.</param>
- void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags);
/// <summary>Gets the result of the <see cref="IValueTaskSource{TResult}"/>.</summary>
/// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param>
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs
index fd68a4985a..e72328ac54 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
@@ -31,7 +32,7 @@ namespace System.Threading.Tasks.Sources
/// <summary>Whether the current operation has completed.</summary>
private bool _completed;
/// <summary>The result with which the operation succeeded, or the default value if it hasn't yet completed or failed.</summary>
- private TResult _result;
+ [AllowNull, MaybeNull] private TResult _result;
/// <summary>The exception with which the operation failed, or null if it hasn't yet completed or completed successfully.</summary>
private ExceptionDispatchInfo? _error;
/// <summary>The current version of this value, used to help prevent misuse.</summary>
@@ -47,7 +48,7 @@ namespace System.Threading.Tasks.Sources
// Reset/update state for the next use/await of this instance.
_version++;
_completed = false;
- _result = default!; // TODO-NULLABLE-GENERIC
+ _result = default!; // TODO-NULLABLE: Remove ! when nullable attributes are respected
_error = null;
_executionContext = null;
_capturedContext = null;
@@ -106,7 +107,7 @@ namespace System.Threading.Tasks.Sources
/// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param>
/// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param>
/// <param name="flags">The flags describing the behavior of the continuation.</param>
- public void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags)
{
if (continuation == null)
{
@@ -175,7 +176,7 @@ namespace System.Threading.Tasks.Sources
case SynchronizationContext sc:
sc.Post(s =>
{
- var tuple = (Tuple<Action<object?>, object?>)s!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ var tuple = (Tuple<Action<object?>, object?>)s!;
tuple.Item1(tuple.Item2);
}, Tuple.Create(continuation, state));
break;
@@ -254,7 +255,7 @@ namespace System.Threading.Tasks.Sources
case SynchronizationContext sc:
sc.Post(s =>
{
- var state = (Tuple<Action<object?>, object?>)s!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ var state = (Tuple<Action<object?>, object?>)s!;
state.Item1(state.Item2);
}, Tuple.Create(_continuation, _continuationState));
break;
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 a4a65922cc..4fb8d9aff9 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
@@ -207,12 +207,14 @@ namespace System.Threading.Tasks
{
Debug.Assert(task != null, "Null Task objects can't be added to the ActiveTasks collection");
+#pragma warning disable CS8634 // TODO-NULLABLE: Remove warning disable when nullable attributes are respected
LazyInitializer.EnsureInitialized(ref s_currentActiveTasks, () => new Dictionary<int, Task>());
+#pragma warning restore CS8634
int taskId = task.Id;
- lock (s_currentActiveTasks!) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ lock (s_currentActiveTasks!) // TODO-NULLABLE: Remove ! when nullable attributes are respected
{
- s_currentActiveTasks![taskId] = task; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ s_currentActiveTasks[taskId] = task;
}
//always return true to keep signature as bool for backwards compatibility
return true;
@@ -427,7 +429,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="action"/> argument is null.
/// </exception>
- public Task(Action<object?> action, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Action<object?> action, object? state)
: this(action, state, null, default, TaskCreationOptions.None, InternalTaskOptions.None, null)
{
}
@@ -444,7 +446,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task(Action<object?> action, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Action<object?> action, object? state, CancellationToken cancellationToken)
: this(action, state, null, cancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, null)
{
}
@@ -465,7 +467,7 @@ namespace System.Threading.Tasks
/// The <paramref name="creationOptions"/> argument specifies an invalid value for <see
/// cref="T:System.Threading.Tasks.TaskCreationOptions"/>.
/// </exception>
- public Task(Action<object?> action, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Action<object?> action, object? state, TaskCreationOptions creationOptions)
: this(action, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, InternalTaskOptions.None, null)
{
}
@@ -490,7 +492,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task(Action<object?> action, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task(Action<object?> action, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
: this(action, state, Task.InternalCurrentIfAttached(creationOptions), cancellationToken, creationOptions, InternalTaskOptions.None, null)
{
}
@@ -634,7 +636,7 @@ namespace System.Threading.Tasks
if (antecedent == null)
{
// if no antecedent was specified, use this task's reference as the cancellation state object
- ctr = cancellationToken.UnsafeRegister(t => ((Task)t!).InternalCancel(false), this); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ ctr = cancellationToken.UnsafeRegister(t => ((Task)t!).InternalCancel(false), this);
}
else
{
@@ -1050,7 +1052,7 @@ namespace System.Threading.Tasks
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
}
- InternalRunSynchronously(scheduler!, waitForCompletion: true); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ InternalRunSynchronously(scheduler!, waitForCompletion: true); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
//
@@ -1356,7 +1358,9 @@ namespace System.Threading.Tasks
/// <returns>The initialized contingent properties object.</returns>
internal ContingentProperties EnsureContingentPropertiesInitialized()
{
- return LazyInitializer.EnsureInitialized(ref m_contingentProperties, () => new ContingentProperties())!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+#pragma warning disable CS8634 // TODO-NULLABLE: Remove warning disable when nullable attributes are respected
+ return LazyInitializer.EnsureInitialized(ref m_contingentProperties, () => new ContingentProperties())!;
+#pragma warning restore CS8634
}
/// <summary>
@@ -1525,7 +1529,7 @@ namespace System.Threading.Tasks
}
}
- return contingentProps.m_completionEvent!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ return contingentProps.m_completionEvent!; // TODO-NULLABLE: Remove ! when compiler specially-recognizes CompareExchange for nullability
}
}
@@ -1815,7 +1819,7 @@ namespace System.Threading.Tasks
lock (props)
{
- props.m_exceptionsHolder!.Add(exceptionObject, representsCancellation); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ props.m_exceptionsHolder!.Add(exceptionObject, representsCancellation); // TODO-NULLABLE: Remove ! when compiler specially-recognizes CompareExchange for nullability
}
}
@@ -3613,13 +3617,13 @@ namespace System.Threading.Tasks
CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions);
Task continuationTask = new ContinuationTaskFromTask(
- this, continuationAction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationAction!, null, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationTask;
}
@@ -3803,13 +3807,13 @@ namespace System.Threading.Tasks
CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions);
Task continuationTask = new ContinuationTaskFromTask(
- this, continuationAction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationAction!, state, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationTask;
}
@@ -4006,13 +4010,13 @@ namespace System.Threading.Tasks
CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions);
Task<TResult> continuationTask = new ContinuationResultTaskFromTask<TResult>(
- this, continuationFunction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationFunction!, null, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationTask;
}
@@ -4213,13 +4217,13 @@ namespace System.Threading.Tasks
CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions);
Task<TResult> continuationTask = new ContinuationResultTaskFromTask<TResult>(
- this, continuationFunction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ this, continuationFunction!, state, // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
creationOptions, internalOptions
);
// Register the continuation. If synchronous execution is requested, this may
// actually invoke the continuation before returning.
- ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
return continuationTask;
}
@@ -4724,7 +4728,7 @@ namespace System.Threading.Tasks
bool returnValue = true;
// Collects incomplete tasks in "waitedOnTaskList"
- for (int i = tasks!.Length - 1; i >= 0; i--) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ for (int i = tasks!.Length - 1; i >= 0; i--) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
Task task = tasks[i];
@@ -4733,7 +4737,7 @@ namespace System.Threading.Tasks
ThrowHelper.ThrowArgumentException(ExceptionResource.Task_WaitMulti_NullTask, ExceptionArgument.tasks);
}
- bool taskIsCompleted = task!.IsCompleted; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ bool taskIsCompleted = task!.IsCompleted; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (!taskIsCompleted)
{
// try inlining the task only if we have an infinite timeout and an empty cancellation token
@@ -5089,7 +5093,7 @@ namespace System.Threading.Tasks
// Make a pass through the loop to check for any tasks that may have
// already been completed, and to verify that no tasks are null.
- for (int taskIndex = 0; taskIndex < tasks!.Length; taskIndex++) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ for (int taskIndex = 0; taskIndex < tasks!.Length; taskIndex++) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
Task task = tasks[taskIndex];
@@ -5098,7 +5102,7 @@ namespace System.Threading.Tasks
ThrowHelper.ThrowArgumentException(ExceptionResource.Task_WaitMulti_NullTask, ExceptionArgument.tasks);
}
- if (signaledTaskIndex == -1 && task!.IsCompleted) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ if (signaledTaskIndex == -1 && task!.IsCompleted) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
// We found our first completed task. Store it, but we can't just return here,
// as we still need to validate the whole array for nulls.
@@ -5150,7 +5154,7 @@ namespace System.Threading.Tasks
if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
var task = new Task();
- bool succeeded = task.TrySetException(exception!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ bool succeeded = task.TrySetException(exception!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
Debug.Assert(succeeded, "This should always succeed on a new task.");
return task;
}
@@ -5164,7 +5168,7 @@ namespace System.Threading.Tasks
if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
var task = new Task<TResult>();
- bool succeeded = task.TrySetException(exception!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ bool succeeded = task.TrySetException(exception!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
Debug.Assert(succeeded, "This should always succeed on a new task.");
return task;
}
@@ -5187,7 +5191,7 @@ namespace System.Threading.Tasks
{
if (!cancellationToken.IsCancellationRequested)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.cancellationToken);
- return new Task<TResult>(true, default!, TaskCreationOptions.None, cancellationToken); // TODO-NULLABLE-GENERIC
+ return new Task<TResult>(true, default!, TaskCreationOptions.None, cancellationToken); // TODO-NULLABLE: Remove ! when nullable attributes are respected
}
/// <summary>Creates a <see cref="Task"/> that's completed due to cancellation with the specified exception.</summary>
@@ -5324,7 +5328,7 @@ namespace System.Threading.Tasks
return Task.FromCanceled(cancellationToken);
// Kick off initial Task, which will call the user-supplied function and yield a Task.
- Task<Task?> task1 = Task<Task?>.Factory.StartNew(function!, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ Task<Task?> task1 = Task<Task?>.Factory.StartNew(function!, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
// Create a promise-style Task to be used as a proxy for the operation
// Set lookForOce == true so that unwrap logic can be on the lookout for OCEs thrown as faults from task1, to support in-delegate cancellation.
@@ -5369,7 +5373,7 @@ namespace System.Threading.Tasks
return Task.FromCanceled<TResult>(cancellationToken);
// Kick off initial Task, which will call the user-supplied function and yield a Task.
- Task<Task<TResult>?> task1 = Task<Task<TResult>?>.Factory.StartNew(function!, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ Task<Task<TResult>?> task1 = Task<Task<TResult>?>.Factory.StartNew(function!, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
// Create a promise-style Task to be used as a proxy for the operation
// Set lookForOce == true so that unwrap logic can be on the lookout for OCEs thrown as faults from task1, to support in-delegate cancellation.
@@ -5492,7 +5496,7 @@ namespace System.Threading.Tasks
if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout
{
- _timer = new TimerQueueTimer(state => ((DelayPromise)state!).CompleteTimedOut(), this, (uint)millisecondsDelay, Timeout.UnsignedInfinite, flowExecutionContext: false); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ _timer = new TimerQueueTimer(state => ((DelayPromise)state!).CompleteTimedOut(), this, (uint)millisecondsDelay, Timeout.UnsignedInfinite, flowExecutionContext: false);
if (IsCanceled)
{
// Handle rare race condition where cancellation occurs prior to our having created and stored the timer, in which case
@@ -5531,7 +5535,7 @@ namespace System.Threading.Tasks
Debug.Assert(token.CanBeCanceled);
_token = token;
- _registration = token.UnsafeRegister(state => ((DelayPromiseWithCancellation)state!).CompleteCanceled(), this); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ _registration = token.UnsafeRegister(state => ((DelayPromiseWithCancellation)state!).CompleteCanceled(), this);
}
private void CompleteCanceled()
@@ -5596,7 +5600,7 @@ namespace System.Threading.Tasks
foreach (var task in tasks)
{
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- taskArray[index++] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ taskArray[index++] = task!; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
return InternalWhenAll(taskArray);
}
@@ -5604,10 +5608,10 @@ namespace System.Threading.Tasks
// Do some argument checking and convert tasks to a List (and later an array).
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
List<Task> taskList = new List<Task>();
- foreach (Task task in tasks!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ foreach (Task task in tasks!) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- taskList.Add(task!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ taskList.Add(task!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
// Delegate the rest to InternalWhenAll()
@@ -5646,7 +5650,7 @@ namespace System.Threading.Tasks
// Do some argument checking and make a defensive copy of the tasks array
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
- int taskCount = tasks!.Length; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ int taskCount = tasks!.Length; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (taskCount == 0) return InternalWhenAll(tasks); // Small optimization in the case of an empty array.
Task[] tasksCopy = new Task[taskCount];
@@ -5654,7 +5658,7 @@ namespace System.Threading.Tasks
{
Task task = tasks[i];
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- tasksCopy[i] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ tasksCopy[i] = task!; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
// The rest can be delegated to InternalWhenAll()
@@ -5840,7 +5844,7 @@ namespace System.Threading.Tasks
foreach (var task in tasks)
{
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- taskArray[index++] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ taskArray[index++] = task!; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
return InternalWhenAll<TResult>(taskArray);
}
@@ -5848,10 +5852,10 @@ namespace System.Threading.Tasks
// Do some argument checking and convert tasks into a List (later an array)
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
List<Task<TResult>> taskList = new List<Task<TResult>>();
- foreach (Task<TResult> task in tasks!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ foreach (Task<TResult> task in tasks!) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- taskList.Add(task!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ taskList.Add(task!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
// Delegate the rest to InternalWhenAll<TResult>().
@@ -5893,7 +5897,7 @@ namespace System.Threading.Tasks
// Do some argument checking and make a defensive copy of the tasks array
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
- int taskCount = tasks!.Length; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ int taskCount = tasks!.Length; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (taskCount == 0) return InternalWhenAll<TResult>(tasks); // small optimization in the case of an empty task array
Task<TResult>[] tasksCopy = new Task<TResult>[taskCount];
@@ -5901,7 +5905,7 @@ namespace System.Threading.Tasks
{
Task<TResult> task = tasks[i];
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- tasksCopy[i] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ tasksCopy[i] = task!; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
// Delegate the rest to InternalWhenAll<TResult>()
@@ -6060,7 +6064,7 @@ namespace System.Threading.Tasks
public static Task<Task> WhenAny(params Task[] tasks)
{
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
- if (tasks!.Length == 0) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ if (tasks!.Length == 0) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks);
}
@@ -6073,7 +6077,7 @@ namespace System.Threading.Tasks
{
Task task = tasks[i];
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- tasksCopy[i] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ tasksCopy[i] = task!; // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
// Previously implemented CommonCWAnyLogic() can handle the rest
@@ -6102,10 +6106,10 @@ namespace System.Threading.Tasks
// Make a defensive copy, as the user may manipulate the tasks collection
// after we return but before the WhenAny asynchronously completes.
List<Task> taskList = new List<Task>();
- foreach (Task task in tasks!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ foreach (Task task in tasks!) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks);
- taskList.Add(task!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ taskList.Add(task!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
if (taskList.Count == 0)
@@ -6597,7 +6601,7 @@ namespace System.Threading.Tasks
ThreadPool.UnsafeQueueUserWorkItem(state =>
{
// InvokeCore(completingTask);
- var tuple = (Tuple<UnwrapPromise<TResult>, Task>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ var tuple = (Tuple<UnwrapPromise<TResult>, Task>)state!;
tuple.Item1.InvokeCore(tuple.Item2);
}, Tuple.Create<UnwrapPromise<TResult>, Task>(this, completingTask));
}
@@ -6673,7 +6677,7 @@ namespace System.Threading.Tasks
if (Task.s_asyncDebuggingEnabled)
RemoveFromActiveTasks(this);
- result = TrySetResult(taskTResult != null ? taskTResult.Result : default!); // TODO-NULLABLE-GENERIC
+ result = TrySetResult(taskTResult != null ? taskTResult.Result : default!); // TODO-NULLABLE: Remove ! when nullable attributes are respected
break;
}
return result;
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs
index 8773eb4159..b0c79e61ba 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs
@@ -150,7 +150,7 @@ namespace System.Threading.Tasks
{
if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
- bool rval = _task.TrySetException(exception!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ bool rval = _task.TrySetException(exception!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
if (!rval && !_task.IsCompleted) SpinUntilCompleted();
return rval;
}
@@ -180,11 +180,11 @@ namespace System.Threading.Tasks
if (exceptions == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exceptions);
List<Exception> defensiveCopy = new List<Exception>();
- foreach (Exception e in exceptions!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ foreach (Exception e in exceptions!) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
if (e == null)
ThrowHelper.ThrowArgumentException(ExceptionResource.TaskCompletionSourceT_TrySetException_NullException, ExceptionArgument.exceptions);
- defensiveCopy.Add(e!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ defensiveCopy.Add(e!); // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
}
if (defensiveCopy.Count == 0)
@@ -216,7 +216,7 @@ namespace System.Threading.Tasks
{
if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
- if (!TrySetException(exception!)) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+ if (!TrySetException(exception!)) // TODO-NULLABLE: Remove ! when [DoesNotReturn] respected
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs
index 65547fb452..fbe77339cc 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs
@@ -492,7 +492,7 @@ namespace System.Threading.Tasks
{
try
{
- ((Action)state!)(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ ((Action)state!)();
}
catch (Exception exception)
{
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs
index 3929a08589..786e132e7b 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs
@@ -396,7 +396,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task StartNew(Action<object?> action, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task StartNew(Action<object?> action, object? state)
{
Task? currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
@@ -425,7 +425,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task StartNew(Action<object?> action, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task StartNew(Action<object?> action, object? state, CancellationToken cancellationToken)
{
Task? currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, state, cancellationToken, GetDefaultScheduler(currTask),
@@ -455,7 +455,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task StartNew(Action<object?> action, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task StartNew(Action<object?> action, object? state, TaskCreationOptions creationOptions)
{
Task? currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
@@ -496,7 +496,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task StartNew(Action<object?> action, object? state, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task StartNew(Action<object?> action, object? state, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
return Task.InternalStartNew(
@@ -657,7 +657,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state)
{
Task? currTask = Task.InternalCurrent;
return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
@@ -690,7 +690,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, CancellationToken cancellationToken)
{
Task? currTask = Task.InternalCurrent;
return Task<TResult>.StartNew(currTask, function, state, cancellationToken,
@@ -724,7 +724,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions)
{
Task? currTask = Task.InternalCurrent;
return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
@@ -769,7 +769,7 @@ namespace System.Threading.Tasks
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
/// </remarks>
- public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
return Task<TResult>.StartNew(
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs
index b6afade5a5..f79a87ac06 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs
@@ -298,7 +298,7 @@ namespace System.Threading.Tasks
Interlocked.CompareExchange(ref s_activeTaskSchedulers, new ConditionalWeakTable<TaskScheduler, object?>(), null);
activeTaskSchedulers = s_activeTaskSchedulers;
}
- activeTaskSchedulers!.Add(this, null); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
+ activeTaskSchedulers!.Add(this, null); // TODO-NULLABLE: Remove ! when compiler specially-recognizes CompareExchange for nullability
}
/// <summary>
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 884ae0b009..75c6fd9a32 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks.Sources;
@@ -415,7 +416,7 @@ namespace System.Threading.Tasks
/// <summary>null if <see cref="_result"/> has the result, otherwise a <see cref="Task{TResult}"/> or a <see cref="IValueTaskSource{TResult}"/>.</summary>
internal readonly object? _obj;
/// <summary>The result to be used if the operation completed successfully synchronously.</summary>
- internal readonly TResult _result;
+ [AllowNull] internal readonly TResult _result;
/// <summary>Opaque value passed through to the <see cref="IValueTaskSource{TResult}"/>.</summary>
internal readonly short _token;
/// <summary>true to continue on the captured context; otherwise, false.</summary>
@@ -449,7 +450,7 @@ namespace System.Threading.Tasks
_obj = task;
- _result = default!; // TODO-NULLABLE-GENERIC
+ _result = default!; // TODO-NULLABLE: Remove ! when nullable attributes are respected
_continueOnCapturedContext = true;
_token = 0;
}
@@ -468,7 +469,7 @@ namespace System.Threading.Tasks
_obj = source;
_token = token;
- _result = default!; // TODO-NULLABLE-GENERIC
+ _result = default!; // TODO-NULLABLE: Remove ! when nullable attributes are respected
_continueOnCapturedContext = true;
}