private async Task <Errorable <Commit[]> > getCommitsRecursively(CommitID id, int depthLevel, int depthMaximum) { // Get the current commit: var eroot = await getCommit(id).ConfigureAwait(continueOnCapturedContext: false); if (eroot.HasErrors) { return(eroot.Errors); } var root = eroot.Value; var rootArr = new Commit[1] { root }; // We have no parents: if (root.Parents.Length == 0) { return(rootArr); } // This is the last depth level: if (depthLevel >= depthMaximum) { return(rootArr); } // Recurse up the commit parents: Task <Errorable <Commit[]> >[] tasks = new Task <Errorable <Commit[]> > [root.Parents.Length]; for (int i = 0; i < root.Parents.Length; ++i) { tasks[i] = getCommitsRecursively(root.Parents[i], depthLevel + 1, depthMaximum); } // Await all the tree retrievals: var allCommits = await Task.WhenAll(tasks).ConfigureAwait(continueOnCapturedContext: false); // Roll up all the errors: ErrorContainer errors = ( from ecms in allCommits where ecms.HasErrors select ecms.Errors ).Aggregate(new ErrorContainer(), (acc, err) => acc + err); if (errors.HasAny) { return(errors); } // Flatten out the tree arrays: var flattened = from ecms in allCommits from cm in ecms.Value select cm; // Return the final array: return(rootArr.Concat(flattened).ToArray(allCommits.Sum(ca => ca.Value.Length) + 1)); }