Esempio n. 1
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>
        ///   创建一个在目标 <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);
        }
        /// <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);
        }
Esempio n. 4
0
 /// <summary>
 /// Creates a TaskScheduler associated with the current Dpjia.UnityTask.SynchronizationContext.
 /// </summary>
 /// <returns></returns>
 public static UnityTaskScheduler FromCurrentSynchronizationContext()
 {
     if (g_defaultContext == null)
     {
         GameObject go = new GameObject();
         go.name          = "unity_task_scheduler";
         g_defaultContext = go.AddComponent <UnityTaskScheduler>();
         DontDestroyOnLoad(go);// 标记,不删除
     }
     return(g_defaultContext);
 }
Esempio n. 5
0
 /// <summary>
 /// try to cancel
 /// </summary>
 /// <param name="p_result"></param>
 /// <returns></returns>
 internal bool TrySetCanceled()
 {
     if (m_isCompleted)
     {
         return(false);
     }
     UnityTaskScheduler.FromCurrentSynchronizationContext().Stop(TaskCoroutine);
     m_isCompleted     = true;
     this.m_isCanceled = true;
     RunContinuations();
     return(true);
 }
Esempio n. 6
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);
        }
Esempio n. 7
0
 /// <summary>
 /// try to cancel
 /// </summary>
 /// <returns></returns>
 internal bool TrySetCanceled()
 {
     if (_isCompleted)
     {
         return(false);
     }
     if (!string.IsNullOrEmpty(CoroutineCode))
     {
         UnityTaskScheduler.Cancel(CoroutineCode);
     }
     _isCompleted = true;
     _isCanceled  = true;
     RunContinuations();
     return(true);
 }
Esempio n. 8
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);
        }
Esempio n. 9
0
 /// <summary>
 /// run tasks in continuation list
 /// </summary>
 private void RunContinuations()
 {
     if (Thread.CurrentThread.IsBackground)
     {
         var continueActions = _continuationActions.ToList();
         UnityTaskScheduler.Post(() =>
         {
             continueActions.ForEach(p => p(this));
         });
         _continuationActions.Clear();
     }
     else
     {
         _continuationActions.ForEach(p => p(this));
         _continuationActions.Clear();
     }
 }
Esempio n. 10
0
        /// <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);
        }