ITaskCompletionAction singleTaskCompletionAction = continuationObject as ITaskCompletionAction;
if (singleTaskCompletionAction != null)
{
- singleTaskCompletionAction.Invoke(this);
+ if (bCanInlineContinuations)
+ {
+ singleTaskCompletionAction.Invoke(this);
+ }
+ else
+ {
+ ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(singleTaskCompletionAction, this), forceGlobal: false);
+ }
LogFinishCompletionNotification();
return;
}
{
Contract.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction");
var action = (ITaskCompletionAction)currentContinuation;
- action.Invoke(this);
+
+ if (bCanInlineContinuations)
+ {
+ action.Invoke(this);
+ }
+ else
+ {
+ ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(action, this), forceGlobal: false);
+ }
}
}
}
}
+ internal sealed class CompletionActionInvoker : IThreadPoolWorkItem
+ {
+ private readonly ITaskCompletionAction m_action;
+ private readonly Task m_completingTask;
+
+ internal CompletionActionInvoker(ITaskCompletionAction action, Task completingTask)
+ {
+ m_action = action;
+ m_completingTask = completingTask;
+ }
+
+ public void ExecuteWorkItem()
+ {
+ m_action.Invoke(m_completingTask);
+ }
+
+ public void MarkAborted(ThreadAbortException tae)
+ {
+ /* NOP */
+ }
+ }
+
// Proxy class for better debugging experience
internal class SystemThreadingTasks_TaskDebugView
{