个人感觉Task 的WaitAny和WhenAny以及TaskFactory 的ContinueWhenAny有相似的地方,而WaitAll和WhenAll以及TaskFactory 的ContinueWhenAll也是相同,但是WaitAny和WhenAny的返回值有所不同。我们首先来看看Task WhenAny和WhenAll 的实现吧,
public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable { //Creates a task that will complete when any of the supplied tasks have completed. public static Task<Task> WhenAny(IEnumerable<Task> tasks) { if (tasks == null) throw new ArgumentNullException("tasks"); Contract.EndContractBlock(); List<Task> taskList = new List<Task>(); foreach (Task task in tasks) { if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks"); taskList.Add(task); } if (taskList.Count == 0) { throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks"); } // Previously implemented CommonCWAnyLogic() can handle the rest return TaskFactory.CommonCWAnyLogic(taskList); } //Creates a task that will complete when all of the supplied tasks have completed. public static Task<TResult[]> WhenAll<TResult>(params Task<TResult>[] tasks) { if (tasks == null) throw new ArgumentNullException("tasks"); Contract.EndContractBlock(); int taskCount = tasks.Length; if (taskCount == 0) return InternalWhenAll<TResult>(tasks); // small optimization in the case of an empty task array Task<TResult>[] tasksCopy = new Task<TResult>[taskCount]; for (int i = 0; i < taskCount; i++) { Task<TResult> task = tasks[i]; if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks"); tasksCopy[i] = task; } return InternalWhenAll<TResult>(tasksCopy); } private static Task<TResult[]> InternalWhenAll<TResult>(Task<TResult>[] tasks) { Contract.Requires(tasks != null, "Expected a non-null tasks array"); return (tasks.Length == 0) ? new Task<TResult[]>(false, new TResult[0], TaskCreationOptions.None, default(CancellationToken)) : new WhenAllPromise<TResult