Example #1
0
        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);
        }