protected internal CoroutineTask(AsyncResult asyncResult) { this.asyncResult = asyncResult; }
/// <summary> /// Creates a task that will complete when all of the supplied tasks have completed. /// </summary> /// <typeparam name="TResult"></typeparam> /// <param name="tasks">The tasks to wait on for completion.</param> /// <returns>A task that represents the completion of all of the supplied tasks.</returns> /// <remarks> /// <para> /// If any of the supplied tasks completes in a faulted state, the returned task will also complete in a Faulted state, /// where its exceptions will contain the aggregation of the set of unwrapped exceptions from each of the supplied tasks. /// </para> /// <para> /// If none of the supplied tasks faulted but at least one of them was canceled, the returned task will end in the Canceled state. /// </para> /// <para> /// If none of the tasks faulted and none of the tasks were canceled, the resulting task will end in the Completed state. /// The Result of the returned task will be set to an array containing all of the results of the supplied tasks in the /// same order as they were provided. /// </para> /// </remarks> public static CoroutineTask <TResult[]> WhenAll <TResult>(params CoroutineTask <TResult>[] tasks) { AsyncResult <TResult[]> result = new AsyncResult <TResult[]>(true); try { if (tasks == null) { throw new ArgumentNullException("tasks"); } int count = tasks.Length; int curr = count; bool isCancelled = false; List <Exception> exceptions = new List <Exception>(); TResult[] array = new TResult[count]; for (int i = 0; i < count; i++) { int index = i; var t = tasks[index]; t.asyncResult.Callbackable().OnCallback((ar) => { try { isCancelled |= ar.IsCancelled; if (ar.Exception != null) { exceptions.Add(ar.Exception); } else { array[index] = (TResult)ar.Result; } } finally { if (Interlocked.Decrement(ref curr) <= 0) { if (isCancelled) { result.SetCancelled(); } else if (exceptions.Count > 0) { result.SetException(new AggregateException(exceptions)); } else { result.SetResult(array); } } } }); } } catch (Exception e) { result.SetException(e); } return(new CoroutineTask <TResult[]>(result)); }