summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs6
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs18
2 files changed, 22 insertions, 2 deletions
diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
index 18888f9367..2fb284a4c7 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
@@ -534,6 +534,10 @@ namespace System.Runtime.CompilerServices
/// <summary>A delegate to the <see cref="MoveNext"/> method.</summary>
public Action MoveNextAction => _moveNextAction ?? (_moveNextAction = new Action(MoveNext));
+ /// <summary>Invokes <see cref="MoveNext"/> when the box is queued to the thread pool and executed as a work item.</summary>
+ void IThreadPoolWorkItem.ExecuteWorkItem() => MoveNext();
+ void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* nop */ }
+
/// <summary>Calls MoveNext on <see cref="StateMachine"/></summary>
public void MoveNext()
{
@@ -884,7 +888,7 @@ namespace System.Runtime.CompilerServices
/// <summary>
/// An interface implemented by all <see cref="AsyncStateMachineBox{TStateMachine, TResult}"/> instances, regardless of generics.
/// </summary>
- internal interface IAsyncStateMachineBox
+ internal interface IAsyncStateMachineBox : IThreadPoolWorkItem
{
/// <summary>Move the state machine forward.</summary>
void MoveNext();
diff --git a/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs b/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs
index dc63a67ddb..7abe63c283 100644
--- a/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs
@@ -787,7 +787,23 @@ namespace System.Threading.Tasks
// If we're not allowed to run here, schedule the action
if (!allowInlining || !IsValidLocationForInlining)
{
- UnsafeScheduleAction(box.MoveNextAction, prevCurrentTask);
+ // If logging is disabled, we can simply queue the box itself as a custom work
+ // item, and its work item execution will just invoke its MoveNext. However, if
+ // logging is enabled, there is pre/post-work we need to do around logging to
+ // match what's done for other continuations, and that requires flowing additional
+ // information into the continuation, which we don't want to burden other cases of the
+ // box with... so, in that case we just delegate to the AwaitTaskContinuation-based
+ // path that already handles this, albeit at the expense of allocating the ATC
+ // object, and potentially forcing the box's delegate into existence, when logging
+ // is enabled.
+ if (TplEtwProvider.Log.IsEnabled())
+ {
+ UnsafeScheduleAction(box.MoveNextAction, prevCurrentTask);
+ }
+ else
+ {
+ ThreadPool.UnsafeQueueCustomWorkItem(box, forceGlobal: false);
+ }
return;
}