Пример #1
0
 protected internal CoroutineTask(AsyncResult asyncResult)
 {
     this.asyncResult = asyncResult;
 }
Пример #2
0
        /// <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));
        }