Beispiel #1
0
 public CoroutineTask(Action action) : this(new AsyncResult())
 {
     Executors.RunOnMainThread(() =>
     {
         try
         {
             action();
             _asyncResult.SetResult();
         }
         catch (Exception e)
         {
             _asyncResult.SetException(e);
         }
     });
 }
Beispiel #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="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, TResult> continuationFunction,
                                                              CoroutineTaskContinuationOptions continuationOptions = CoroutineTaskContinuationOptions.None)
        {
            AsyncResult <TResult> result = new AsyncResult <TResult>(true);

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

                    TResult value = continuationFunction(this);
                    result.SetResult(value);
                }
                catch (Exception e)
                {
                    result.SetException(e);
                }
            });
            return(new CoroutineTask <TResult>(result));
        }
Beispiel #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="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> continuationAction,
                                          CoroutineTaskContinuationOptions continuationOptions = CoroutineTaskContinuationOptions.None)
        {
            AsyncResult result = new AsyncResult(true);

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

                    continuationAction(this);
                    result.SetResult();
                }
                catch (Exception e)
                {
                    result.SetException(e);
                }
            });
            return(new CoroutineTask(result));
        }
Beispiel #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)
        {
            AsyncResult <CoroutineTask <TResult> > result = new AsyncResult <CoroutineTask <TResult> >(true);

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

                int count = tasks.Length;
                for (int 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));
        }
Beispiel #5
0
 public static IAsyncResult Void()
 {
     if (voidResult == null)
     {
         var result = new AsyncResult();
         result.SetResult();
         voidResult = result;
     }
     return(voidResult);
 }
Beispiel #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");
                }

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

            try
            {
                if (tasks == null)
                {
                    throw new ArgumentNullException(nameof(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));
        }