/// <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> /// 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, IEnumerator> p_continuation, System.Threading.Tasks.CancellationToken p_cancellationToken) { Func <UnityTask, UnityTask> continuation = t => { return(UnityTask.Run(() => p_continuation(t))); }; return(ContinueWith(continuation, p_cancellationToken)); }
/// <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); }
internal Task(Action action, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) : this(action, null, parent, cancellationToken, creationOptions, internalOptions, scheduler) { CapturedContext = ExecutionContext.Capture(); }
/// <summary> /// An internal constructor used by the factory methods on task and its descendent(s). /// This variant does not capture the ExecutionContext; it is up to the caller to do that. /// </summary> /// <param name="action">An action to execute.</param> /// <param name="state">Optional state to pass to the action.</param> /// <param name="parent">Parent of Task.</param> /// <param name="cancellationToken">A CancellationToken for the task.</param> /// <param name="scheduler">A task scheduler under which the task will run.</param> /// <param name="creationOptions">Options to control its execution.</param> /// <param name="internalOptions">Internal options to control its execution</param> internal Task(Delegate action, object state, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) { if (action == null) { #pragma warning disable IDE0016 throw new ArgumentNullException(nameof(action)); #pragma warning restore IDE0016 } if (scheduler == null) { #pragma warning disable IDE0016 throw new ArgumentNullException(nameof(scheduler)); #pragma warning restore IDE0016 } Contract.EndContractBlock(); // This is readonly, and so must be set in the constructor // Keep a link to your parent if: (A) You are attached, or (B) you are self-replicating. if ( (creationOptions & TaskCreationOptions.AttachedToParent) != 0 || (internalOptions & InternalTaskOptions.SelfReplicating) != 0 ) { _parent = parent; } Id = Interlocked.Increment(ref _lastId) - 1; _status = (int)TaskStatus.Created; if ( _parent != null && (creationOptions & TaskCreationOptions.AttachedToParent) != 0 && (_parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0 ) { _parent.AddNewChild(); } ExecutingTaskScheduler = scheduler; Action = action; State = state; _waitHandle = new ManualResetEventSlim(false); if ((creationOptions & ~(TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler | TaskCreationOptions.PreferFairness | TaskCreationOptions.RunContinuationsAsynchronously)) != 0) { throw new ArgumentOutOfRangeException(nameof(creationOptions)); } // Throw exception if the user specifies both LongRunning and SelfReplicating if ((creationOptions & TaskCreationOptions.LongRunning) != 0 && (internalOptions & InternalTaskOptions.SelfReplicating) != 0) { throw new InvalidOperationException("An attempt was made to create a LongRunning SelfReplicating task."); } if ((internalOptions & InternalTaskOptions.ContinuationTask) != 0) { // For continuation tasks or TaskCompletionSource.Tasks, begin life in the // WaitingForActivation state rather than the Created state. _status = (int)TaskStatus.WaitingForActivation; } CreationOptions = creationOptions; _internalOptions = internalOptions; // if we have a non-null cancellationToken, allocate the contingent properties to save it // we need to do this as the very last thing in the construction path, because the CT registration could modify m_stateFlags if (cancellationToken.CanBeCanceled) { AssignCancellationToken(cancellationToken, null, null); } }
public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : this(action, null, InternalCurrentIfAttached(creationOptions), cancellationToken, creationOptions, InternalTaskOptions.None, TaskScheduler.Default) { // Empty }
internal Task(Action <object> action, object state, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) : this((Delegate)action, state, parent, cancellationToken, creationOptions, internalOptions, scheduler) { CapturedContext = ExecutionContext.Capture(); }
public void Wait(CancellationToken cancellationToken) { PrivateWait(cancellationToken, true); }
public bool Wait(int milliseconds, CancellationToken cancellationToken) { if (milliseconds < -1) { throw new ArgumentOutOfRangeException(nameof(milliseconds)); } if (milliseconds == -1) { Wait(cancellationToken); return(true); } var start = ThreadingHelper.TicksNow(); do { CancellationCheck(cancellationToken); switch (Status) { case TaskStatus.WaitingForActivation: WaitAntecedent(cancellationToken, milliseconds, start); ExecutingTaskScheduler.InternalTryExecuteTaskInline(this, true); break; case TaskStatus.Created: case TaskStatus.WaitingToRun: case TaskStatus.Running: case TaskStatus.WaitingForChildrenToComplete: var waitHandle = _waitHandle.Value; waitHandle?.Wait ( TimeSpan.FromMilliseconds ( milliseconds - ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start) ), cancellationToken ); break; case TaskStatus.RanToCompletion: return(true); case TaskStatus.Canceled: ThrowIfExceptional(true); return(true); case TaskStatus.Faulted: ThrowIfExceptional(true); return(true); default: // Should not happen continue; } } while (ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start) < milliseconds); switch (Status) { case TaskStatus.RanToCompletion: return(true); case TaskStatus.Canceled: ThrowIfExceptional(true); return(true); case TaskStatus.Faulted: ThrowIfExceptional(true); return(true); default: return(false); } }
public Task(Func <object, TResult> function, object state, CancellationToken token, TaskCreationOptions options) : base(null, state, token, options) { this.function = function; this.state = state; }
public Task(Action action, CancellationToken cancellationToken) : this(action, null, null, cancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, TaskScheduler.Default) { // Empty }
public Task(Func <object, TResult> function, object state, CancellationToken token) : this(function, state, token, TaskCreationOptions.None) { }
public Task(Func <TResult> function, CancellationToken token, TaskCreationOptions options) : this((o) => function(), null, token, options) { }
public Task <TNewResult> ContinueWith <TNewResult> (Func <Task <TResult>, TNewResult> a, CancellationToken token, TaskContinuationOptions options, TaskScheduler scheduler) { Task <TNewResult> t = new Task <TNewResult> ((o) => a((Task <TResult>)o), this, token, GetCreationOptions(options)); ContinueWithCore(t, options, scheduler); return(t); }
public Task <TNewResult> ContinueWith <TNewResult> (Func <Task <TResult>, TNewResult> a, CancellationToken token) { return(ContinueWith <TNewResult> (a, token, TaskContinuationOptions.None, TaskScheduler.Current)); }
public Task ContinueWith(Action <Task <TResult> > a, CancellationToken token) { return(ContinueWith(a, token, TaskContinuationOptions.None, TaskScheduler.Current)); }