Beispiel #1
0
 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);
 }
Beispiel #2
0
 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);
 }
Beispiel #3
0
        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));
        }
Beispiel #4
0
 protected void SetContinuation(TaskBase continuation, TaskContinuationOptions runOptions)
 {
     Token.ThrowIfCancellationRequested();
     Task.ContinueWith(_ =>
     {
         Token.ThrowIfCancellationRequested();
         ((TaskBase)(object)continuation).Schedule();
     },
                       Token,
                       runOptions,
                       TaskManager.GetScheduler(continuation.Affinity));
 }
Beispiel #5
0
 /// <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);
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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));
        }
Beispiel #8
0
        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);
        }
Beispiel #9
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);
        }
Beispiel #10
0
 protected void SetContinuation(TaskBase continuation, TaskContinuationOptions runOptions)
 {
     Task.ContinueWith(_ => ((TaskBase)(object)continuation).Run(), Token,
                       runOptions,
                       TaskManager.GetScheduler(continuation.Affinity));
 }