From 9321d394788d5f708cde22006268f45af06d9cfc Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sun, 11 Oct 2020 03:21:05 +0200 Subject: [PATCH] Add fast paths to WhenAny(IEnumerable) (#38896) * Add fast paths to WhenAny(IEnumerable) Adds fast paths in case `tasks` is an array or an `ICollection` * Remove cast from slow path for WhenAll and WhenAny --- .../src/System/Threading/Tasks/Task.cs | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index 5caf5c0..c6cbb14 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -5469,15 +5469,15 @@ namespace System.Threading.Tasks /// public static Task WhenAll(IEnumerable tasks) { - // Take a more efficient path if tasks is actually an array - if (tasks is Task[] taskArray) - { - return WhenAll(taskArray); - } - // Skip a List allocation/copy if tasks is a collection if (tasks is ICollection taskCollection) { + // Take a more efficient path if tasks is actually an array + if (tasks is Task[] taskArray) + { + return WhenAll(taskArray); + } + int index = 0; taskArray = new Task[taskCollection.Count]; foreach (Task task in tasks) @@ -6077,6 +6077,25 @@ namespace System.Threading.Tasks /// public static Task WhenAny(IEnumerable tasks) { + // Skip a List allocation/copy if tasks is a collection + if (tasks is ICollection taskCollection) + { + // Take a more efficient path if tasks is actually an array + if (tasks is Task[] taskArray) + { + return WhenAny(taskArray); + } + + int index = 0; + taskArray = new Task[taskCollection.Count]; + foreach (Task task in tasks) + { + if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); + taskArray[index++] = task; + } + return TaskFactory.CommonCWAnyLogic(taskArray); + } + if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); // Make a defensive copy, as the user may manipulate the tasks collection -- 2.7.4