Пример #1
0
 public CoroutineTask(Action action) : this(new AsyncResult())
 {
     Executors.RunOnMainThread(() =>
     {
         try
         {
             action();
             asyncResult.SetResult();
         }
         catch (Exception e)
         {
             asyncResult.SetException(e);
         }
     });
 }
Пример #2
0
        /// <summary>
        ///     Creates a continuation that executes when the target <see cref="CoroutineTask" /> completes.
        /// </summary>
        /// <param name="continuationFunction">
        ///     An action to run when the <see cref="CoroutineTask" /> completes. When run, the delegate will be
        ///     passed the completed task as an argument.
        /// </param>
        /// <param name="state">The parameter of the action.</param>
        /// <param name="continuationOptions">
        ///     Options for when the continuation is scheduled and how it behaves. This includes criteria, such
        ///     as <see cref="CoroutineTaskContinuationOptions.OnCanceled">OnCanceled</see>
        ///     , as well as execution options, such as
        ///     <see cref="CoroutineTaskContinuationOptions.OnCompleted">OnCompleted</see>.
        /// </param>
        /// <returns>A new continuation <see cref="CoroutineTask" />.</returns>
        /// <remarks>
        ///     The returned <see cref="CoroutineTask" /> will not be scheduled for execution until the current task has
        ///     completed.
        /// </remarks>
        public CoroutineTask <TResult> ContinueWith <TResult>(Func <CoroutineTask, object, TResult> continuationFunction,
                                                              object state, CoroutineTaskContinuationOptions continuationOptions = CoroutineTaskContinuationOptions.None)
        {
            var result = new AsyncResult <TResult>(true);

            asyncResult.Callbackable().OnCallback(ar =>
            {
                try
                {
                    var executable = IsExecutable(ar, continuationOptions);
                    if (!executable)
                    {
                        result.SetCancelled();
                        return;
                    }

                    TResult value = continuationFunction(this, state);
                    result.SetResult(value);
                }
                catch (Exception e)
                {
                    result.SetException(e);
                }
            });
            return(new CoroutineTask <TResult>(result));
        }
Пример #3
0
        /// <summary>
        ///     Creates a continuation that executes when the target <see cref="CoroutineTask" /> completes.
        /// </summary>
        /// <param name="continuationAction">
        ///     An action to run when the <see cref="CoroutineTask" /> completes. When run, the delegate will be
        ///     passed the completed task as an argument.
        /// </param>
        /// <param name="state">The parameter of the action.</param>
        /// <param name="continuationOptions">
        ///     Options for when the continuation is scheduled and how it behaves. This includes criteria, such
        ///     as <see cref="CoroutineTaskContinuationOptions.OnCanceled">OnCanceled</see>
        ///     , as well as execution options, such as
        ///     <see cref="CoroutineTaskContinuationOptions.OnCompleted">OnCompleted</see>.
        /// </param>
        /// <returns>A new continuation <see cref="CoroutineTask" />.</returns>
        /// <remarks>
        ///     The returned <see cref="CoroutineTask" /> will not be scheduled for execution until the current task has
        ///     completed.
        /// </remarks>
        public CoroutineTask ContinueWith(Action <CoroutineTask, object> continuationAction, object state,
                                          CoroutineTaskContinuationOptions continuationOptions = CoroutineTaskContinuationOptions.None)
        {
            AsyncResult result = new AsyncResult(true);

            asyncResult.Callbackable().OnCallback(ar =>
            {
                try
                {
                    var executable = IsExecutable(ar, continuationOptions);
                    if (!executable)
                    {
                        result.SetCancelled();
                        return;
                    }

                    continuationAction(this, state);
                    result.SetResult();
                }
                catch (Exception e)
                {
                    result.SetException(e);
                }
            });
            return(new CoroutineTask(result));
        }
Пример #4
0
        /// <summary>
        ///     Creates a task that will complete when any 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 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 <TResult> > WhenAny <TResult>(params CoroutineTask <TResult>[] tasks)
        {
            var result = new AsyncResult <CoroutineTask <TResult> >(true);

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

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

            return(new CoroutineTask <CoroutineTask <TResult> >(result));
        }
Пример #5
0
        /// <summary>
        /// </summary>
        /// <param name="task"></param>
        /// <param name="runOnMainThread"></param>
        public AsyncTask(Action task, bool runOnMainThread = false)
        {
            if (task == null)
                throw new ArgumentNullException("task");

            result = new AsyncResult();
            if (runOnMainThread)
                action = WrapAction(() =>
                {
                    Executors.RunOnMainThread(task, true);
                    result.SetResult();
                });
            else
                action = WrapAction(() =>
                {
                    task();
                    result.SetResult();
                });
        }
Пример #6
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));
        }
Пример #7
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)
        {
            var result = new AsyncResult <TResult[]>(true);

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

                var count       = tasks.Length;
                var curr        = count;
                var isCancelled = false;
                var exceptions  = new List <Exception>();
                var array       = new TResult[count];
                for (var i = 0; i < count; i++)
                {
                    var 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));
        }