From 4ce60481d75d919e34cac056b90627cdaa500524 Mon Sep 17 00:00:00 2001 From: Alfredo Menendez Sancho Date: Wed, 11 Nov 2015 18:31:34 -0800 Subject: [PATCH] Fix Task so that RunContinuationsAsynchronously flag works with all types of continuation --- src/mscorlib/src/System/Threading/Tasks/Task.cs | 41 +++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/mscorlib/src/System/Threading/Tasks/Task.cs b/src/mscorlib/src/System/Threading/Tasks/Task.cs index ebd8c2b..2194300 100644 --- a/src/mscorlib/src/System/Threading/Tasks/Task.cs +++ b/src/mscorlib/src/System/Threading/Tasks/Task.cs @@ -3610,7 +3610,14 @@ namespace System.Threading.Tasks 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; } @@ -3687,7 +3694,15 @@ namespace System.Threading.Tasks { 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); + } } } } @@ -6650,6 +6665,28 @@ namespace System.Threading.Tasks } + 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 { -- 2.7.4