From: Alfredo Menendez Sancho Date: Thu, 12 Nov 2015 02:31:34 +0000 (-0800) Subject: Fix Task so that RunContinuationsAsynchronously flag works with all types of continuation X-Git-Tag: accepted/tizen/base/20180629.140029~6174^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4ce60481d75d919e34cac056b90627cdaa500524;p=platform%2Fupstream%2Fcoreclr.git Fix Task so that RunContinuationsAsynchronously flag works with all types of continuation --- 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 {