/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }