Exemple #1
0
        /// <summary>
        ///   创建一个任务,该任务将在可枚举集合中的所有 <see cref="T:UnityEngine.TaskExtension.UnityTask" /> 对象都完成时完成。
        /// </summary>
        /// <param name="tasks">等待完成的任务。</param>
        /// <returns>表示所有提供的任务的完成情况的任务。</returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="tasks" /> 参数为 <see langword="null" />。
        /// </exception>
        /// <exception cref="T:System.ArgumentException">
        ///   此 <paramref name="tasks" /> 集合包含 <see langword="null" /> 任务。
        /// </exception>
        public static UnityTask WhenAll(IEnumerable <UnityTask> tasks)
        {
            var taskArray = tasks.ToArray();

            if (taskArray.Length == 0)
            {
                return(FromResult(0));
            }
            var uTcs = new UnityTaskCompletionSource <object>();

            Factory.ContinueWhenAll(taskArray, t =>
            {
                Exception[] exceptions = taskArray.Where(p => p.IsFaulted).Select(p => p.Exception).ToArray();
                if (exceptions.Length > 0)
                {
                    foreach (var e in exceptions)
                    {
                        Debug.LogError(e);
                    }
                    uTcs.SetException(new System.AggregateException(exceptions));
                }
                else if (taskArray.Any(p => p.IsCanceled))
                {
                    uTcs.SetCanceled();
                }
                else
                {
                    uTcs.SetResult(0);
                }
            });
            return(uTcs.Task);
        }
Exemple #2
0
        /// <summary>
        /// Creates a new, completed task for the given result.
        /// </summary>
        /// <typeparam name="T">The result type of the task.</typeparam>
        /// <param name="p_result"></param>
        /// <returns>A completed task.</returns>
        public static UnityTask <T> FromResult <T>(T p_result)
        {
            var tcs = new UnityTaskCompletionSource <T>();

            tcs.SetResult(p_result);
            return(tcs.Task);
        }
Exemple #3
0
        /// <summary>
        ///   创建 <see cref="T:UnityEngine.TaskExtension.UnityTask" />,取消操作。
        /// </summary>
        /// <returns>取消的任务。</returns>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        /// </exception>
        public static UnityTask FromCanceled()
        {
            var uTcs = new UnityTaskCompletionSource <int>();

            uTcs.SetCanceled();
            return(uTcs.Task);
        }
Exemple #4
0
        /// <summary>
        /// 创建 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" />,它是以指定的异常来完成的。
        /// </summary>
        /// <typeparam name="T">任务返回的结果的类型</typeparam>
        /// <param name="exception">完成任务的异常</param>
        /// <returns>出错的任务</returns>
        public static UnityTask <T> FromException <T>(Exception exception)
        {
            var uTcs = new UnityTaskCompletionSource <T>();

            uTcs.SetException(exception);
            return(uTcs.Task);
        }
Exemple #5
0
        /// <summary>
        /// Creates a new, completed task for the given result.
        /// </summary>
        /// <typeparam name="T">The result type of the task.</typeparam>
        /// <param name="p_result"></param>
        /// <returns>A completed task.</returns>
        public static UnityTask FromException(Exception p_exception)
        {
            var tcs = new UnityTaskCompletionSource <int>();

            tcs.SetException(p_exception);
            return(tcs.Task);
        }
Exemple #6
0
        /// <summary>
        /// Creates a task that is complete when all of the provided tasks are complete.
        /// If any of the tasks has an exception, all exceptions raised in the tasks will
        /// be aggregated into the returned task. Otherwise, if any of the tasks is cancelled,
        /// the returned task will be cancelled.
        /// </summary>
        /// <param name="p_tasks">The tasks to aggregate.</param>
        /// <returns>A task that is complete when all of the provided tasks are complete.</returns>
        public static UnityTask WhenAll(IEnumerable <UnityTask> p_tasks)
        {
            var taskArr = p_tasks.ToArray();

            if (taskArr.Length == 0)
            {
                return(UnityTask.FromResult(0));
            }
            var tcs = new UnityTaskCompletionSource <object>();

            UnityTask.Factory.ContinueWhenAll(taskArr, _ =>
            {
                var exceptions = taskArr.Where(p => p.IsFaulted).Select(p => p.Exception).ToArray();
                if (exceptions.Length > 0)
                {
                    tcs.SetException(new System.Threading.Tasks.AggregateException(exceptions));
                }
                else if (taskArr.Any(t => t.IsCanceled))
                {
                    tcs.SetCanceled();
                }
                else
                {
                    tcs.SetResult(0);
                }
            });
            return(tcs.Task);
        }
        /// <summary>
        ///   创建一个在目标 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 成功执行时异步执行的延续任务。
        /// </summary>
        /// <typeparam name="TResult">该任务的结果的类型。</typeparam>
        /// <param name="task">目标<see cref="T:UnityEngine.TaskExtension.UnityTask`1" /></param>
        /// <param name="continuation">
        ///   在 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 完成时要运行的操作。
        ///    在运行时,委托将作为一个参数传递给完成的任务。
        /// </param>
        /// <returns>
        ///   一个新的延续 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" />。
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="continuation" /> 参数为 <see langword="null" />。
        /// </exception>
        public static UnityTask <TResult> OnSuccess <TResult>(this UnityTask task, Func <UnityTask, TResult> continuation)
        {
            UnityTaskCompletionSource <TResult> uTcs = new UnityTaskCompletionSource <TResult>();

            task.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    uTcs.TrySetException(t.Exception);
                }
                else if (t.IsCanceled)
                {
                    uTcs.TrySetCanceled();
                }
                else
                {
                    try
                    {
                        TResult result = continuation(t);
                        uTcs.TrySetResult(result);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                        uTcs.TrySetException(e);
                    }
                }
            });
            return(uTcs.Task);
        }
        /// <summary>
        ///   创建一个在目标 <see cref="T:System.Threading.Tasks.Task" /> 成功执行时异步执行的<see cref="T:UnityEngine.TaskExtension.UnityTask" />延续任务。
        /// </summary>
        /// <param name="task">目标<see cref="T:System.Threading.Tasks.Task" /></param>
        /// <param name="continuation">
        ///   在 <see cref="T:System.Threading.Tasks.Task" /> 完成时要运行的操作。
        ///    在运行时,委托将作为一个参数传递给完成的任务。
        /// </param>
        /// <param name="cancellationToken">将指派给新的延续任务的 <see cref="P:System.Threading.Tasks.TaskFactory.CancellationToken" />。</param>
        /// <returns>
        ///   一个新的延续 <see cref="T:System.Threading.Tasks.Task" />。
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="continuation" /> 参数为 <see langword="null" />。
        /// </exception>
        public static UnityTask ContinueToForeground(this Task task, Action <Task> continuation,
                                                     CancellationToken cancellationToken)
        {
            UnityTaskCompletionSource <object> uTcs = new UnityTaskCompletionSource <object>();
            var cancellation = cancellationToken.Register(() => uTcs.TrySetCanceled());

            task.ContinueWith(p =>
            {
                UnityTaskScheduler.Post(() =>
                {
                    try
                    {
                        continuation(p);
                        uTcs.TrySetResult(0);
                    }
                    catch (Exception e)
                    {
                        //Debug.LogError(e);
                        uTcs.TrySetException(e);
                    }
                    finally
                    {
                        cancellation.Dispose();
                    }
                });
            }, cancellationToken);
            return(uTcs.Task);
        }
        /// <summary>
        /// 空任务
        /// </summary>
        /// <typeparam name="TResult">该任务的结果的类型。</typeparam>
        /// <returns></returns>
        public static UnityTask <IEnumerable <TResult> > EndForNull <TResult>()
        {
            UnityTaskCompletionSource <IEnumerable <TResult> > uTcs = new UnityTaskCompletionSource <IEnumerable <TResult> >();

            uTcs.SetResult(null);
            return(uTcs.Task);
        }
        /// <summary>
        ///   创建一个在目标 <see cref="T:UnityEngine.TaskExtension.UnityTask" /> 成功执行时异步执行的延续任务。
        /// </summary>
        /// <param name="task">目标<see cref="T:UnityEngine.TaskExtension.UnityTask" /></param>
        /// <param name="continuation">
        ///   在 <see cref="T:UnityEngine.TaskExtension.UnityTask" /> 完成时要运行的操作。
        ///    在运行时,委托将作为一个参数传递给完成的任务。
        /// </param>
        /// <returns>
        ///   一个新的延续 <see cref="T:UnityEngine.TaskExtension.UnityTask" />。
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="continuation" /> 参数为 <see langword="null" />。
        /// </exception>
        public static UnityTask OnSuccess(this UnityTask task, Action <UnityTask> continuation)
        {
            UnityTaskCompletionSource <object> uTcs = new UnityTaskCompletionSource <object>();

            task.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    uTcs.TrySetException(t.Exception);
                }
                else if (t.IsCanceled)
                {
                    uTcs.TrySetCanceled();
                }
                else
                {
                    try
                    {
                        continuation(t);
                        uTcs.TrySetResult(null);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                        uTcs.TrySetException(e);
                    }
                }
            });
            return(uTcs.Task);
        }
        /// <summary>
        /// Unwraps a nested task, producing a task that is complete when both the outer
        /// and inner tasks are complete and that has the inner task's result.
        /// This is primarily useful for chaining asynchronous operations together.
        /// </summary>
        /// <param name="task">The task to unwrap.</param>
        /// <returns>A new task that is complete when both the outer and inner tasks
        /// are complete and that has the inner task's result.</returns>
        public static UnityTask <T> Unwrap <T>(this UnityTask <UnityTask <T> > task)
        {
            var tcs = new UnityTaskCompletionSource <T>();

            task.ContinueWith((UnityTask <UnityTask <T> > t) =>
            {
                if (t.IsFaulted)
                {
                    tcs.TrySetException(t.Exception);
                }
                else if (t.IsCanceled)
                {
                    tcs.TrySetCanceled();
                }
                else
                {
                    t.Result.ContinueWith(delegate(UnityTask <T> inner)
                    {
                        if (inner.IsFaulted)
                        {
                            tcs.TrySetException(inner.Exception);
                        }
                        else if (inner.IsCanceled)
                        {
                            tcs.TrySetCanceled();
                        }
                        else
                        {
                            tcs.TrySetResult(inner.Result);
                        }
                    });
                }
            });
            return(tcs.Task);
        }
Exemple #12
0
        /// <summary>
        /// Creates a task that will complete successfully after the given timespan.
        /// </summary>
        /// <param name="p_timespan">The amount of time to wait.</param>
        /// <returns>A new task.</returns>
        public static UnityTask RunDelay(float p_seconds, CancellationToken p_cancellationToken)
        {
            var tcs          = new UnityTaskCompletionSource <int>();
            var cancellation = p_cancellationToken.Register(() => tcs.TrySetCanceled());

            tcs.Task.TaskGenerator = () => DelayCoroutine(p_seconds);
            tcs.Task.ReturnResult  = _ =>
            {
                try
                {
                    tcs.TrySetResult(0);
                    cancellation.Dispose();
                }
                catch (Exception e)
                {
                    tcs.TrySetException(e);
                    cancellation.Dispose();
                }
            };
            if (Thread.CurrentThread.IsBackground)// 如果当前不在前端线程,则切换
            {
                ForegroundInvoker.Invoke(() =>
                {
                    tcs.Task.TaskCoroutine = UnityTaskScheduler.FromCurrentSynchronizationContext().Post(tcs.Task.TaskGenerator(), tcs.Task.ReturnResult);
                });
            }
            else
            {
                tcs.Task.TaskCoroutine = UnityTaskScheduler.FromCurrentSynchronizationContext().Post(tcs.Task.TaskGenerator(), tcs.Task.ReturnResult);
            }
            return(tcs.Task);
        }
        /// <summary>
        /// Unwraps a nested task, producing a task that is complete when both the outer and inner tasks are complete. This is primarily useful for chaining asynchronous operations together.
        /// </summary>
        /// <param name="p_task">The task to unwrap.</param>
        /// <returns>A new task that is complete when both the outer and inner tasks are complete.</returns>
        public static UnityTask Unwrap(this UnityTask <UnityTask> p_task)
        {
            var tcs = new UnityTaskCompletionSource <object>();

            p_task.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    tcs.TrySetException(t.Exception);
                }
                else if (t.IsCanceled)
                {
                    tcs.TrySetCanceled();
                }
                else
                {
                    p_task.Result.ContinueWith(inner =>
                    {
                        if (inner.IsFaulted)
                        {
                            tcs.TrySetException(inner.Exception);
                        }
                        else if (inner.IsCanceled)
                        {
                            tcs.TrySetCanceled();
                        }
                        else
                        {
                            tcs.TrySetResult(null);
                        }
                    });
                }
            });
            return(tcs.Task);
        }
Exemple #14
0
        /// <summary>
        ///   创建指定结果的、成功完成的 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" />。
        /// </summary>
        /// <param name="result">存储入已完成任务的结果。</param>
        /// <typeparam name="T">任务返回的结果的类型。</typeparam>
        /// <returns>已成功完成的任务。</returns>
        public static UnityTask <T> FromResult <T>(T result)
        {
            var uTcs = new UnityTaskCompletionSource <T>();

            uTcs.SetResult(result);
            return(uTcs.Task);
        }
        /// <summary>
        ///   创建一个在目标 <see cref="T:System.Threading.Tasks.Task`1" /> 成功执行时异步执行的<see cref="T:UnityEngine.TaskExtension.UnityTask`1" />延续任务。
        /// </summary>
        /// <param name="task">目标<see cref="T:System.Threading.Tasks.Task`1" /></param>
        /// <param name="continuation">
        ///   在 <see cref="T:System.Threading.Tasks.Task`1" /> 完成时要运行的操作。
        ///    在运行时,委托将作为一个参数传递给完成的任务。
        /// </param>
        /// <param name="cancellationToken">将指派给新的延续任务的 <see cref="P:System.Threading.Tasks.TaskFactory.CancellationToken" />。</param>
        /// <returns>
        ///   一个新的延续 <see cref="T:System.Threading.Tasks.Task" />。
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="continuation" /> 参数为 <see langword="null" />。
        /// </exception>
        public static UnityTask <TResult> ContinueToForeground <TIn, TResult>(this Task <TIn> task, Func <Task <TIn>, TResult> continuation,
                                                                              CancellationToken cancellationToken)
        {
            UnityTaskCompletionSource <TResult> uTcs = new UnityTaskCompletionSource <TResult>();
            var cancellation = cancellationToken.Register(() => uTcs.TrySetCanceled());

            task.ContinueWith(p =>
            {
                UnityTaskScheduler.Post(() =>
                {
                    try
                    {
                        var result = continuation(p);
                        uTcs.TrySetResult(result);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                        uTcs.TrySetException(e);
                    }
                    finally
                    {
                        cancellation.Dispose();
                    }
                });
            }, cancellationToken);
            return(uTcs.Task);
        }
Exemple #16
0
        /// <summary>任何提供的任务已完成时,创建将完成的任务。</summary>
        /// <param name="tasks">等待完成的任务。</param>
        /// <returns>
        ///   表示提供的任务之一已完成的任务。
        ///     返回任务的结果是完成的任务。
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="tasks" /> 参数为 <see langword="null" />。
        /// </exception>
        /// <exception cref="T:System.ArgumentException">
        ///   <paramref name="tasks" />数组包含 null 的任务,或者为空。
        /// </exception>
        internal static UnityTask <UnityTask> WhenAny(IEnumerable <UnityTask> tasks)
        {
            var uTcs = new UnityTaskCompletionSource <UnityTask>();

            foreach (var task in tasks)
            {
                task.ContinueWith(p => uTcs.TrySetResult(p));
            }
            return(uTcs.Task);
        }
Exemple #17
0
        /// <summary>
        /// Waits for any of the provided Task objects to complete execution.
        /// </summary>
        /// <param name="p_tasks"></param>
        /// <returns></returns>
        internal static UnityTask <UnityTask> WhenAny(IEnumerable <UnityTask> p_tasks)
        {
            var tcs = new UnityTaskCompletionSource <UnityTask>();

            foreach (var task in p_tasks)
            {
                task.ContinueWith(t => tcs.TrySetResult(t));
            }
            return(tcs.Task);
        }
Exemple #18
0
        /// <summary>
        /// 创建一个任务,该任务将在可枚举集合中的所有 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 对象都完成时完成。
        /// </summary>
        /// <param name="tasks">等待完成的任务。</param>
        /// <returns>表示所有提供的任务的完成情况的任务。</returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="tasks" /> 参数为 <see langword="null" />。
        /// </exception>
        /// <exception cref="T:System.ArgumentException">
        ///   此 <paramref name="tasks" /> 集合包含 <see langword="null" /> 任务。
        /// </exception>
        public static UnityTask <List <TResult> > WhenAll <TResult>(IEnumerable <UnityTask <TResult> > tasks)
        {
            var unityTasks = tasks.ToList();
            var uTcs       = new UnityTaskCompletionSource <List <TResult> >();

            Factory.ContinueWhenAll(unityTasks, p =>
            {
                var listResult = unityTasks.Select(t => p[t.GetHashCode().ToString()]).ToList();
                uTcs.TrySetResult(listResult);
            });
            return(uTcs.Task);
        }
Exemple #19
0
        /// <summary>
        ///   创建一个在目标 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 完成时可接收取消标记并以异步方式执行的延续任务。
        /// </summary>
        /// <param name="continuation">
        ///   在 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 完成时要运行的操作。
        ///    在运行时,委托将作为一个自变量传递给完成的任务。
        /// </param>
        /// <param name="cancellationToken">
        ///   将指派给新的延续任务的 <see cref="P:System.Threading.Tasks.TaskFactory.CancellationToken" />。
        /// </param>
        /// <returns>
        ///   一个新的延续 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" />。
        /// </returns>
        /// <exception cref="T:System.ObjectDisposedException">
        ///   <see cref="T:System.Threading.CancellationTokenSource" /> 创建该标记已被释放。
        /// </exception>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="continuation" /> 参数为 null。
        /// </exception>
        public UnityTask <UnityTask <TResult> > ContinueWith <TResult>(Func <UnityTask, UnityTask <TResult> > continuation,
                                                                       CancellationToken cancellationToken)
        {
            bool completed = false;
            UnityTaskCompletionSource <UnityTask <TResult> > uTcs       = new UnityTaskCompletionSource <UnityTask <TResult> >();
            CancellationTokenRegistration cancellationTokenRegistration =
                cancellationToken.Register(() => uTcs.TrySetCanceled());

            completed = _isCompleted;
            if (!completed)
            {
                _continuationActions.Add(t =>
                {
                    try
                    {
                        var result = continuation(t);
                        uTcs.TrySetResult(result);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                        uTcs.TrySetException(e);
                    }
                    finally
                    {
                        cancellationTokenRegistration.Dispose();
                    }
                });
            }
            else
            {
                UnityTaskScheduler.Post(() =>
                {
                    try
                    {
                        var result = continuation(this);
                        uTcs.TrySetResult(result);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                        uTcs.TrySetException(e);
                    }
                    finally
                    {
                        cancellationTokenRegistration.Dispose();
                    }
                });
            }

            return(uTcs.Task);
        }
Exemple #20
0
        /// <summary>
        ///   创建一个在目标 <see cref="T:UnityEngine.TaskExtension.UnityTask" /> 完成时可接收取消标记并以异步方式执行的延续任务。
        /// </summary>
        /// <param name="continuation">
        ///   在 <see cref="T:UnityEngine.TaskExtension.UnityTask" /> 完成时要运行的操作。
        ///    在运行时,委托将作为一个自变量传递给完成的任务。
        /// </param>
        /// <param name="cancellationToken">
        ///   将指派给新的延续任务的 <see cref="P:System.Threading.Tasks.TaskFactory.CancellationToken" />。
        /// </param>
        /// <returns>
        ///   一个新的延续 <see cref="T:UnityEngine.TaskExtension.UnityTask" />。
        /// </returns>
        /// <exception cref="T:System.ObjectDisposedException">
        ///   <see cref="T:System.Threading.CancellationTokenSource" /> 创建该标记已被释放。
        /// </exception>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="continuation" /> 参数为 null。
        /// </exception>
        public UnityTask ContinueWith(Action <UnityTask> continuation, CancellationToken cancellationToken)
        {
            bool completed = false;
            UnityTaskCompletionSource <int> uTcs = new UnityTaskCompletionSource <int>();
            CancellationTokenRegistration   cancellationTokenRegistration =
                cancellationToken.Register(() => uTcs.TrySetCanceled());

            completed = _isCompleted;
            if (!completed)
            {
                _continuationActions.Add(t =>
                {
                    try
                    {
                        continuation(this);
                        uTcs.TrySetResult(0);
                    }
                    catch (Exception e)
                    {
                        uTcs.TrySetException(e);
                    }
                    finally
                    {
                        cancellationTokenRegistration.Dispose();
                    }
                });
            }
            else
            {
                UnityTaskScheduler.Post(() =>
                {
                    try
                    {
                        continuation(this);
                        uTcs.TrySetResult(0);
                    }
                    catch (Exception e)
                    {
                        uTcs.TrySetException(e);
                    }
                    finally
                    {
                        cancellationTokenRegistration.Dispose();
                    }
                });
            }
            return(uTcs.Task);
        }
Exemple #21
0
        /// <summary>
        /// Registers a continuation for the task that will run when the task is complete.
        /// </summary>
        /// <typeparam name="T">The type returned by the continuation.</typeparam>
        /// <param name="p_continuation">The continuation to run after the task completes.
        /// The function takes the completed task as an argument and can return a value.</param>
        /// <returns>A new Task that returns the value returned by the continuation after both
        /// the task and the continuation are complete.</returns>
        public UnityTask ContinueWith(Action <UnityTask> p_continuation, System.Threading.Tasks.CancellationToken p_cancellationToken)
        {
            bool completed = false;

            UnityTaskCompletionSource <int> utcs        = new UnityTaskCompletionSource <int>();
            CancellationTokenRegistration   cancelToken = p_cancellationToken.Register(() => utcs.TrySetCanceled());

            // 此处防止判断为false之后正好执行完毕
            completed = IsCompleted;
            if (!completed)
            {
                m_continuationActions.Add(t =>
                {
                    try
                    {
                        p_continuation(this);
                        utcs.TrySetResult(0);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                });
            }
            else
            {
                ForegroundInvoker.Invoke(() =>// 如果当前不在前端线程,则切换
                {
                    try
                    {
                        p_continuation(this);
                        utcs.TrySetResult(0);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                });
            }

            return(utcs.Task);
        }
        /// <summary>
        /// OnSuccess
        /// </summary>
        /// <param name="p_task"></param>
        /// <param name="p_continuation"></param>
        /// <returns></returns>
        public static UnityTask OnSuccess(this UnityTask p_task, Action <UnityTask> p_continuation)
        {
            UnityTaskCompletionSource <object> utcs = new UnityTaskCompletionSource <object>();

            p_task.ContinueWith(t =>
            {
                if (!t.IsFaulted && !t.IsCanceled)
                {
                    p_continuation(t);
                    utcs.TrySetResult(null);
                }
                else
                {
                    utcs.TrySetException(t.Exception);
                }
            });
            return(utcs.Task);
        }
        /// <summary>
        /// Creates and starts a Task<TResult>
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <param name="p_func"></param>
        /// <returns></returns>
        public UnityTask <TResult> StartNew <TResult>(Func <System.Collections.IEnumerator> p_func)
        {
            var tcs = new UnityTaskCompletionSource <TResult>();

            tcs.Task.TaskGenerator = () => p_func();
            tcs.Task.ReturnResult  = result =>
            {
                try
                {
                    tcs.SetResult((TResult)result);
                }
                catch (Exception e)
                {
                    tcs.SetException(e);
                }
            };
            tcs.Task.TaskCoroutine = UnityTaskScheduler.FromCurrentSynchronizationContext().Post(tcs.Task.TaskGenerator(), tcs.Task.ReturnResult);
            return(tcs.Task);
        }
        /// <summary>
        /// OnSuccess
        /// </summary>
        /// <param name="p_task"></param>
        /// <param name="p_continuation"></param>
        /// <returns></returns>
        public static UnityTask <TResult> OnSuccess <TResult>(this UnityTask p_task, Func <UnityTask, TResult> p_continuation)
        {
            UnityTaskCompletionSource <TResult> utcs = new UnityTaskCompletionSource <TResult>();

            p_task.ContinueWith(t =>
            {
                if (!t.IsFaulted && !t.IsCanceled)
                {
                    TResult result = p_continuation(t);
                    utcs.TrySetResult(result);
                }
                else
                {
                    utcs.TrySetException(t.Exception);
                }
            });

            return(utcs.Task);
        }
        /// <summary>
        /// Creates a continuation task that starts when a set of specified tasks has completed.
        /// </summary>
        /// <param name="p_tasks"></param>
        /// <param name="p_continuationAction"></param>
        /// <returns></returns>
        public UnityTask ContinueWhenAll(UnityTask[] p_tasks, Func <UnityTask[], System.Collections.IEnumerator> p_continuationAction)
        {
            int remaining = p_tasks.Length;
            var tcs       = new UnityTaskCompletionSource <UnityTask[]>();

            if (remaining == 0)
            {
                tcs.TrySetResult(p_tasks);
            }
            foreach (var task in p_tasks)
            {
                task.ContinueWith(_ =>
                {
                    remaining--;
                    if (remaining == 0)
                    {
                        tcs.TrySetResult(p_tasks);
                    }
                });
            }
            return(tcs.Task.ContinueWith <UnityTask[]>(t => p_continuationAction(t.Result)));
        }
        /// <summary>
        ///   创建一个代理 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 表示异步操作的Task
        /// </summary>
        /// <param name="task">
        ///   进行解包的任务。
        /// </param>
        /// <typeparam name="T">该任务的结果的类型。</typeparam>
        /// <returns>
        ///   一个 <see cref="T:UnityEngine.TaskExtension.UnityTask`1" /> 表示所提供的异步操作Task
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        ///   如果引发的异常 <paramref name="task" /> 参数为 null。
        /// </exception>
        public static UnityTask <T> Unwrap <T>(this UnityTask <UnityTask <T> > task)
        {
            var uTcs = new UnityTaskCompletionSource <T>();

            task.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    Debug.LogError(t.Exception);
                    uTcs.TrySetException(t.Exception);
                }
                else if (t.IsCanceled)
                {
                    uTcs.TrySetCanceled();
                }
                else
                {
                    t.Result.ContinueWith(inner =>
                    {
                        if (inner.IsFaulted)
                        {
                            Debug.LogError(inner.Exception);
                            uTcs.TrySetException(inner.Exception);
                        }
                        else if (inner.IsCanceled)
                        {
                            uTcs.TrySetCanceled();
                        }
                        else
                        {
                            uTcs.TrySetResult(inner.Result);
                        }
                    });
                }
            });
            return(uTcs.Task);
        }
        /// <summary>
        /// switch to foreground processor, UnityTask
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="p_task"></param>
        /// <param name="p_continuation"></param>
        /// <returns></returns>
        public static UnityTask <TResult> ContinueToForeground <T, TResult>(this Task <T> p_task, Func <Task <T>, TResult> p_continuation, CancellationToken p_cancellationToken)
        {
            UnityTaskCompletionSource <TResult> utcs = new UnityTaskCompletionSource <TResult>();
            var cancellation = p_cancellationToken.Register(() => utcs.TrySetCanceled());

            p_task.ContinueWith(t =>
            {
                UnityEngine.Processor.ForegroundInvoker.Invoke(() =>
                {
                    try
                    {
                        var result = p_continuation(t);
                        utcs.TrySetResult(result);
                        cancellation.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancellation.Dispose();
                    }
                });
            });
            return(utcs.Task);
        }
Exemple #28
0
        /// <summary>
        /// Registers a continuation for the task that will run when the task is complete.
        /// </summary>
        /// <typeparam name="T">The type returned by the continuation.</typeparam>
        /// <param name="p_continuation">The continuation to run after the task completes.
        /// The function takes the completed task as an argument and can return a value.</param>
        /// <param name="p_cancellationToken">The cancellation token.</param>
        /// <returns>A new Task that returns the value returned by the continuation after both
        /// the task and the continuation are complete.</returns>
        public UnityTask <UnityTask> ContinueWith(Func <UnityTask, UnityTask> p_continuation, System.Threading.Tasks.CancellationToken p_cancellationToken)
        {
            bool completed = false;

            UnityTaskCompletionSource <UnityTask> utcs        = new UnityTaskCompletionSource <UnityTask>();
            CancellationTokenRegistration         cancelToken = p_cancellationToken.Register(() => utcs.TrySetCanceled());

            // 此处防止判断为false之后正好执行完毕
            completed = IsCompleted;
            if (!completed)
            {
                m_continuationActions.Add(t =>
                {
                    //if (t.IsFaulted)
                    //{
                    //    utcs.TrySetException(t.Exception);
                    //    cancelToken.Dispose();
                    //}
                    //else
                    //{
                    try
                    {
                        UnityTask result = p_continuation(t);
                        utcs.TrySetResult(result);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                    //}
                });
            }
            else
            {
                ForegroundInvoker.Invoke(() =>
                {
                    //if (this.IsFaulted)
                    //{
                    //    utcs.TrySetException(this.Exception);
                    //    cancelToken.Dispose();
                    //}
                    //else
                    //{
                    try
                    {
                        UnityTask result = p_continuation(this);
                        utcs.TrySetResult(result);
                        cancelToken.Dispose();
                    }
                    catch (Exception ex)
                    {
                        utcs.TrySetException(ex);
                        cancelToken.Dispose();
                    }
                    //}
                });
            }

            return(utcs.Task);
        }