// object is completed after the awaiter.IsCompleted but before the awaiter.OnCompleted.
if (_schedulingContext == null)
{
- QueueUserWorkItem(continuation, state);
+ if (_executionContext == null)
+ {
+ UnsafeQueueUserWorkItem(continuation, state);
+ }
+ else
+ {
+ QueueUserWorkItem(continuation, state);
+ }
}
else if (sc != null)
{
private void UnsafeQueueSetCompletionAndInvokeContinuation() =>
ThreadPool.UnsafeQueueUserWorkItem(this, preferLocal: false);
+ private void UnsafeQueueUserWorkItem(Action<object?> action, object? state) =>
+ ThreadPool.UnsafeQueueUserWorkItem(action, state, preferLocal: false);
+
private static void QueueUserWorkItem(Action<object?> action, object? state) =>
ThreadPool.QueueUserWorkItem(action, state, preferLocal: false);
Task.Factory.StartNew(s => ((AsyncOperation<TResult>)s).SetCompletionAndInvokeContinuation(), this,
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
+ private void UnsafeQueueUserWorkItem(Action<object?> action, object? state) =>
+ QueueUserWorkItem(action, state);
+
private static void QueueUserWorkItem(Action<object?> action, object? state) =>
Task.Factory.StartNew(action, state,
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
private void UnsafeQueueSetCompletionAndInvokeContinuation() =>
ThreadPool.UnsafeQueueUserWorkItem(static s => ((AsyncOperation<TResult>)s).SetCompletionAndInvokeContinuation(), this);
+ private void UnsafeQueueUserWorkItem(Action<object?> action, object? state) =>
+ QueueUserWorkItem(action, state);
+
private static void QueueUserWorkItem(Action<object?> action, object? state) =>
Task.Factory.StartNew(action, state,
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
Assert.True(vt.IsCompletedSuccessfully);
Assert.Equal(continueOnCapturedContext != false, schedulerWasFlowed);
- if (completeBeforeOnCompleted) // OnCompleted will simply queue using a mechanism that happens to flow
+ if (completeBeforeOnCompleted)
{
- Assert.True(executionContextWasFlowed);
+ // OnCompleted may or may not flow ExecutionContext here; it's not needed,
+ // and we avoid it when it's easy, but it's also not wrong to do so.
}
else
{