Ejemplo n.º 1
0
        /// <summary>
        ///     Creates a task that will complete when any of the supplied tasks have completed.
        /// </summary>
        /// <param name="tasks">The tasks to wait on for completion.</param>
        /// <returns>
        ///     A task that represents the completion of one of the supplied tasks.  The return Task's Result is the task that
        ///     completed.
        /// </returns>
        /// <remarks>
        ///     The returned task will complete when any of the supplied tasks has completed.  The returned task will always end in
        ///     the Completed state
        ///     with its Result set to the first task to complete.  This is true even if the first task to complete ended in the
        ///     Canceled or Faulted state.
        /// </remarks>
        public static CoroutineTask <CoroutineTask> WhenAny(params CoroutineTask[] tasks)
        {
            var result = new AsyncResult <CoroutineTask>(true);

            try
            {
                if (tasks == null)
                {
                    throw new ArgumentNullException("tasks");
                }

                var count = tasks.Length;
                for (var i = 0; i < count; i++)
                {
                    CoroutineTask task = tasks[i];
                    task.asyncResult.Callbackable().OnCallback(ar =>
                    {
                        if (!result.IsDone)
                        {
                            result.SetResult(task);
                        }
                    });
                }
            }
            catch (Exception e)
            {
                result.SetException(e);
            }

            return(new CoroutineTask <CoroutineTask>(result));
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Creates a task that will complete when all of the supplied tasks have completed.
        /// </summary>
        /// <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.
        ///     </para>
        /// </remarks>
        public static CoroutineTask WhenAll(params CoroutineTask[] tasks)
        {
            AsyncResult result = new AsyncResult(true);

            try
            {
                if (tasks == null)
                {
                    throw new ArgumentNullException("tasks");
                }

                var count       = tasks.Length;
                var curr        = count;
                var isCancelled = false;
                var exceptions  = new List <Exception>();
                for (var i = 0; i < count; i++)
                {
                    CoroutineTask task = tasks[i];
                    task.asyncResult.Callbackable().OnCallback(ar =>
                    {
                        isCancelled |= ar.IsCancelled;
                        if (ar.Exception != null)
                        {
                            exceptions.Add(ar.Exception);
                        }

                        if (Interlocked.Decrement(ref curr) <= 0)
                        {
                            if (isCancelled)
                            {
                                result.SetCancelled();
                            }
                            else if (exceptions.Count > 0)
                            {
                                result.SetException(new AggregateException(exceptions));
                            }
                            else
                            {
                                result.SetResult();
                            }
                        }
                    });
                }
            }
            catch (Exception e)
            {
                result.SetException(e);
            }

            return(new CoroutineTask(result));
        }