internal virtual ITask Finally <T>(T continuation) where T : ITask { Guard.ArgumentNotNull(continuation, "continuation"); continuation.SetDependsOn(this); this.continuation = (TaskBase)(object)continuation; this.continuationAlways = true; DependsOn?.SetFaultHandler((TaskBase)(object)continuation); return(continuation); }
internal virtual ITask Finally <T>(T taskToContinueWith) where T : TaskBase { Guard.ArgumentNotNull(taskToContinueWith, nameof(taskToContinueWith)); continuation = (TaskBase)(object)taskToContinueWith; continuationAlways = true; continuation.SetDependsOn(this); DependsOn?.SetFaultHandler((TaskBase)(object)continuation); return(continuation); }
protected TaskBase GetTopMostTask(TaskBase ret, bool onlyCreatedState) { ret = (!onlyCreatedState || Task.Status == TaskStatus.Created ? this : ret); var depends = DependsOn; if (depends == null) { return(ret); } return(depends.GetTopMostTask(ret, onlyCreatedState)); }
protected void SetContinuation(TaskBase continuation, TaskContinuationOptions runOptions) { Token.ThrowIfCancellationRequested(); Task.ContinueWith(_ => { Token.ThrowIfCancellationRequested(); ((TaskBase)(object)continuation).Schedule(); }, Token, runOptions, TaskManager.GetScheduler(continuation.Affinity)); }
/// <summary> /// This does not set a dependency between the two tasks. Instead, /// the Start method grabs the state of the previous task to pass on /// to the next task via previousSuccess and previousException /// </summary> /// <param name="handler"></param> internal void SetFaultHandler(TaskBase handler) { Task.ContinueWith(t => { Token.ThrowIfCancellationRequested(); handler.Start(t); }, Token, TaskContinuationOptions.OnlyOnFaulted, TaskManager.GetScheduler(handler.Affinity)); DependsOn?.SetFaultHandler(handler); }
public virtual T Then <T>(T cont, bool always = false) where T : ITask { Guard.ArgumentNotNull(cont, nameof(cont)); var taskBase = ((TaskBase)(object)cont); var firstTaskBase = taskBase.GetTopMostTask() ?? taskBase; firstTaskBase.SetDependsOn(this); this.continuation = firstTaskBase; this.continuationAlways = always; return(cont); }
protected TaskBase GetTopMostTask(TaskBase ret, bool onlyCreated, bool onlyUnstartedChain) { ret = (!onlyCreated || Task.Status == TaskStatus.Created ? this : ret); var depends = DependsOn; if (depends == null) { // if we're at the top of the chain and the chain has already been started // and we only care about unstarted chains, return null if (onlyUnstartedChain && Task.Status != TaskStatus.Created) { return(null); } return(ret); } return(depends.GetTopMostTask(ret, onlyCreated, onlyUnstartedChain)); }
public virtual T Then <T>(T nextTask, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) where T : ITask { Guard.ArgumentNotNull(nextTask, nameof(nextTask)); var nextTaskBase = ((TaskBase)(object)nextTask); // find the task at the top of the chain nextTaskBase = nextTaskBase.GetTopMostTask() ?? nextTaskBase; // make the next task dependent on this one so it can get values from us nextTaskBase.SetDependsOn(this); if (runOptions == TaskRunOptions.OnSuccess) { this.continuationOnSuccess = nextTaskBase; // if there are fault handlers in the chain we're appending, propagate them // up this chain as well if (nextTaskBase.continuationOnFailure != null) { SetFaultHandler(nextTaskBase.continuationOnFailure); } else if (nextTaskBase.continuationOnAlways != null) { SetFaultHandler(nextTaskBase.continuationOnAlways); } if (nextTaskBase.catchHandler != null) { Catch(nextTaskBase.catchHandler); } if (nextTaskBase.finallyHandler != null) { Finally(nextTaskBase.finallyHandler); } } else if (runOptions == TaskRunOptions.OnFailure) { this.continuationOnFailure = nextTaskBase; DependsOn?.SetFaultHandler(nextTaskBase); } else { this.continuationOnAlways = nextTaskBase; DependsOn?.SetFaultHandler(nextTaskBase); } return(nextTask); }
public virtual T Then <T>(T nextTask, TaskRunOptions runOptions = TaskRunOptions.OnSuccess, bool taskIsTopOfChain = false) where T : ITask { Guard.ArgumentNotNull(nextTask, nameof(nextTask)); var nextTaskBase = ((TaskBase)(object)nextTask); // find the task at the top of the chain if (!taskIsTopOfChain) { nextTaskBase = nextTaskBase.GetTopMostTask() ?? nextTaskBase; } // make the next task dependent on this one so it can get values from us nextTaskBase.SetDependsOn(this); var nextTaskFinallyHandler = nextTaskBase.finallyHandler; if (runOptions == TaskRunOptions.OnSuccess) { this.continuationOnSuccess = nextTaskBase; // if there are fault handlers in the chain we're appending, propagate them // up this chain as well if (nextTaskBase.continuationOnFailure != null) { SetFaultHandler(nextTaskBase.continuationOnFailure); } else if (nextTaskBase.continuationOnAlways != null) { SetFaultHandler(nextTaskBase.continuationOnAlways); } if (nextTaskBase.catchHandler != null) { Catch(nextTaskBase.catchHandler); } if (nextTaskFinallyHandler != null) { Finally(nextTaskFinallyHandler); } } else if (runOptions == TaskRunOptions.OnFailure) { this.continuationOnFailure = nextTaskBase; DependsOn?.Then(nextTaskBase, TaskRunOptions.OnFailure, true); } else { this.continuationOnAlways = nextTaskBase; DependsOn?.SetFaultHandler(nextTaskBase); } // if the current task has a fault handler, attach it to the chain we're appending if (finallyHandler != null) { TaskBase endOfChainTask = (TaskBase)nextTaskBase.GetEndOfChain(); while (endOfChainTask != this && endOfChainTask != null) { endOfChainTask.finallyHandler += finallyHandler; endOfChainTask = endOfChainTask.DependsOn; } } return(nextTask); }
protected void SetContinuation(TaskBase continuation, TaskContinuationOptions runOptions) { Task.ContinueWith(_ => ((TaskBase)(object)continuation).Run(), Token, runOptions, TaskManager.GetScheduler(continuation.Affinity)); }