Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Fast-path GetStateMachineBox #21875

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
/// <typeparam name="TStateMachine">Specifies the type of the async state machine.</typeparam>
/// <param name="stateMachine">The state machine.</param>
/// <returns>The "boxed" state machine.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private IAsyncStateMachineBox GetStateMachineBox<TStateMachine>(
ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
Expand All @@ -445,6 +446,19 @@ private IAsyncStateMachineBox GetStateMachineBox<TStateMachine>(
return stronglyTypedBox;
}

// We haven't created the IAsyncStateMachineBox yet, create it
return CreateStateMachineBox(ref stateMachine, currentContext);
}

/// <summary>Creates the "boxed" state machine object.</summary>
/// <typeparam name="TStateMachine">Specifies the type of the async state machine.</typeparam>
/// <param name="stateMachine">The state machine.</param>
/// <param name="currentContext">The current <see cref="ExecutionContext"/> to initialize the state machine with.</param>
/// <returns>The "boxed" state machine.</returns>
[MethodImpl(MethodImplOptions.NoInlining)]
private IAsyncStateMachineBox CreateStateMachineBox<TStateMachine>(ref TStateMachine stateMachine,
ExecutionContext currentContext) where TStateMachine : IAsyncStateMachine
{
// The least common case: we have a weakly-typed boxed. This results if the debugger
// or some other use of reflection accesses a property like ObjectIdForDebugger or a
// method like SetNotificationForWaitCompletion prior to the first await happening. In
Expand Down Expand Up @@ -479,7 +493,7 @@ private IAsyncStateMachineBox GetStateMachineBox<TStateMachine>(

// At this point, m_task should really be null, in which case we want to create the box.
// However, in a variety of debugger-related (erroneous) situations, it might be non-null,
// e.g. if the Task property is examined in a Watch window, forcing it to be lazily-intialized
// e.g. if the Task property is examined in a Watch window, forcing it to be lazily-initialized
// as a Task<TResult> rather than as an AsyncStateMachineBox. The worst that happens in such
// cases is we lose the ability to properly step in the debugger, as the debugger uses that
// object's identity to track this specific builder/state machine. As such, we proceed to
Expand Down