Allow some ITaskCompletionActions to always run synchronously
authorstephentoub <stoub@microsoft.com>
Mon, 18 Jan 2016 12:26:14 +0000 (07:26 -0500)
committerstephentoub <stoub@microsoft.com>
Mon, 18 Jan 2016 12:26:14 +0000 (07:26 -0500)
commit0163ed29ca05275f94101051284be9a8ccf235ed
tree0ba7935df3d18ca98721318ab851e63494936453
parent893dc96ccf9b4163ff5506d8ef248a55734b9b74
Allow some ITaskCompletionActions to always run synchronously

A few internal Task completion actions do a known and small quantity of work, without any potential to run arbitrary code, e.g. a completion action used in Task.Wait to set a ManualResetEventSlim.  Such actions used to typically run synchronously, but after https://github.com/dotnet/coreclr/pull/2026 can be forced to run asynchronously.  These few actions are considered purely internal implementation details of TPL, need not be subject to forcing continuations to run asynchronously, and have perf benefits to always being run synchronously, e.g. calling Wait on a RunContinuationsAsynchronously task shouldn't require a work item to be queued to unblock the task.

This commit adds a property to ITaskCompletionAction that we can check to determine whether it's ok to force the continuation to run synchronously even if the system says we should be running all continuations asynchronously.  Only those actions which are safe are annotated as such.  We only invoke this interface property getter in cases where we're about to fall back to allocating and queueing a work item, so the cost of the extra interface call is acceptable for the benefits it provides.  As all of this is internal, it can also be tweaked further in the future.
src/mscorlib/src/System/IO/Stream.cs
src/mscorlib/src/System/Threading/Tasks/Task.cs
src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs