public async Task RunningDifferentTasksDependingOnPreviousResult() { var callOrder = new List <string>(); var taskEnd = new ActionTask(Token, () => callOrder.Add("chain completed")) { Name = "Chain Completed" }; var final = taskEnd.Finally((_, __) => { }, TaskAffinity.Concurrent); var taskStart = new FuncTask <bool>(Token, _ => { callOrder.Add("chain start"); return(false); }) { Name = "Chain Start" } .Then(new ActionTask <bool>(Token, (_, __) => { callOrder.Add("failing"); throw new InvalidOperationException(); }) { Name = "Failing" }); taskStart.Then(new ActionTask(Token, () => { callOrder.Add("on failure"); }) { Name = "On Failure" }, runOptions: TaskRunOptions.OnFailure) .Then(taskEnd, taskIsTopOfChain: true); taskStart.Then(new ActionTask(Token, () => { callOrder.Add("on success"); }) { Name = "On Success" }, runOptions: TaskRunOptions.OnSuccess) .Then(taskEnd, taskIsTopOfChain: true); await final.StartAndSwallowException(); Console.WriteLine(String.Join(",", callOrder.ToArray())); CollectionAssert.AreEqual(new string[] { "chain start", "failing", "on failure", "chain completed" }, callOrder); }
public async Task MergingTwoChainsWorks() { var callOrder = new List <string>(); var dependsOrder = new List <ITask>(); var innerChainTask1 = new ActionTask(TaskEx.FromResult(LogAndReturnResult(callOrder, "chain2 completed1", true))); var innerChainTask2 = innerChainTask1.Then(_ => { callOrder.Add("chain2 FuncTask<string>"); return("1"); }); var innerChainTask3 = innerChainTask2 .Finally((s, e, d) => { callOrder.Add("chain2 Finally"); return(d); }); var outerChainTask1 = new FuncTask <int>(Token, _ => { callOrder.Add("chain1 FuncTask<int>"); return(1); }); var outerChainTask2 = outerChainTask1.Then(innerChainTask3); var outerChainTask3 = outerChainTask2 .Finally((s, e) => { callOrder.Add("chain1 Finally"); }); await outerChainTask3.StartAwait(); var dependsOn = outerChainTask3; while (dependsOn != null) { dependsOrder.Add(dependsOn); dependsOn = dependsOn.DependsOn; } Assert.AreEqual(innerChainTask3, outerChainTask2); CollectionAssert.AreEqual(new ITask[] { outerChainTask1, innerChainTask1, innerChainTask2, innerChainTask3, outerChainTask3 }, dependsOrder.Reverse <ITask>().ToArray()); CollectionAssert.AreEqual(new string[] { "chain2 completed1", "chain1 FuncTask<int>", "chain2 FuncTask<string>", "chain2 Finally", "chain1 Finally" }, callOrder); }
public async Task DoubleSchedulingStartsOnlyOnce() { var runOrder = new List <string>(); var queue = new TaskQueue(); var task1 = new FuncTask <string>(Token, () => { runOrder.Add("1"); return("2"); }); task1.OnStart += _ => runOrder.Add("start 1"); task1.OnEnd += (a, b, c, d) => runOrder.Add("end 1"); var task2 = new FuncTask <string, string>(Token, (_, str) => { runOrder.Add(str); return("3"); }); task2.OnStart += _ => runOrder.Add("start 2"); task2.OnEnd += (a, b, c, d) => runOrder.Add("end 2"); var task3 = new FuncTask <string, string>(Token, (_, str) => { runOrder.Add(str); return("4"); }); task3.OnStart += _ => runOrder.Add("start 3"); task3.OnEnd += (a, b, c, d) => runOrder.Add("end 3"); queue.Queue(task1.Then(task2).Then(task3)); await queue.StartAwait(); var expected = new string[] { "start 1", "1", "end 1", "start 2", "2", "end 2", "start 3", "3", "end 3", }; Assert.AreEqual(expected.Join(","), runOrder.Join(",")); }
public IEnumerator DoubleSchedulingStartsOnlyOnce() { using (var test = StartTest()) { var runOrder = new List <string>(); var queue = new TaskQueue(test.TaskManager); var task1 = new FuncTask <string>(test.TaskManager, () => { runOrder.Add("1"); return("2"); }); task1.OnStart += _ => runOrder.Add("start 1"); task1.OnEnd += (a, b, c, d) => runOrder.Add("end 1"); var task2 = new FuncTask <string, string>(test.TaskManager, (_, str) => { runOrder.Add(str); return("3"); }); task2.OnStart += _ => runOrder.Add("start 2"); task2.OnEnd += (a, b, c, d) => runOrder.Add("end 2"); var task3 = new FuncTask <string, string>(test.TaskManager, (_, str) => { runOrder.Add(str); return("4"); }); task3.OnStart += _ => runOrder.Add("start 3"); task3.OnEnd += (a, b, c, d) => runOrder.Add("end 3"); queue.Queue(task1.Then(task2).Then(task3)); // wait for the tasks to finish foreach (var frame in StartAndWaitForCompletion(queue)) { yield return(frame); } var expected = new string[] { "start 1", "1", "end 1", "start 2", "2", "end 2", "start 3", "3", "end 3", }; Assert.AreEqual(expected.Join(","), runOrder.Join(",")); } }
public IEnumerator RunningDifferentTasksDependingOnSuccessOrFailure() { using (var test = StartTest()) { var callOrder = new List <string>(); ITask taskStart = new FuncTask <bool>(test.TaskManager, _ => { Console.WriteLine("task start"); callOrder.Add("chain start"); return(false); }) { Name = "Chain Start" }; // this runs because we're forcing a failure up the chain ITask taskOnFailure = new ActionTask(test.TaskManager, () => { Console.WriteLine("task failure"); callOrder.Add("on failure"); }) { Name = "On Failure" }; // if success - this never runs because we're forcing a failure before it ITask taskOnSuccess = new ActionTask(test.TaskManager, () => { Console.WriteLine("task success"); callOrder.Add("on success"); }) { Name = "On Success" }; // this will always run because we're adding it after explicit fail/success tasks var taskEnd = new ActionTask(test.TaskManager, () => { Console.WriteLine("task completed"); callOrder.Add("chain completed"); }) { Name = "Chain Completed" }; // start + forced failure taskStart = taskStart .Then(new ActionTask <bool>(test.TaskManager, (_, __) => { Console.WriteLine("task throw"); callOrder.Add("failing"); throw new InvalidOperationException(); }) { Name = "Failing" }); // add the failure chain taskStart .Then(taskOnFailure, runOptions: TaskRunOptions.OnFailure) .Then(taskEnd, taskIsTopOfChain: true); // add the success chain taskStart .Then(taskOnSuccess, runOptions: TaskRunOptions.OnSuccess) .Then(taskEnd, taskIsTopOfChain: true); // taskEnd is added to both chains but only runs once // wait for the tasks to finish foreach (var frame in StartAndWaitForCompletion(taskEnd)) { yield return(frame); } Assert.AreEqual(new string[] { "chain start", "failing", "on failure", "chain completed" }.Join(","), callOrder.Join(",")); } }