// CommitsInfo returns a list of commit information for these tree entries in the state of // given commit and subpath. It takes advantages of concurrency to speed up the process. // The returned list has the same number of items as tree entries, so the caller can access // them via slice indices. public async Task <List <EntryCommitInfo> > CommitsInfo(Commit commit, params CommitsInfoOptions[] opts) { if (Entries.Count == 0) { return(new List <EntryCommitInfo>()); } var opt = new CommitsInfoOptions(); if (opts.Length > 0) { opt = opts[0]; } if (opt.MaxConcurrency <= 0) { opt.MaxConcurrency = Tree.DefaultProcessCount; } var results = new ConcurrentBag <EntryCommitInfo>(); using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(opt.MaxConcurrency)) { List <Task> tasks = new List <Task>(); foreach (var item in Entries) { await concurrencySemaphore.WaitAsync(); tasks.Add(Task.Run(async() => { try { var info = new EntryCommitInfo { Entry = item }; var ePath = System.IO.Path.Combine(string.IsNullOrEmpty(opt.Path)?"":opt.Path, item.Name); info.Commit = await commit.CommitByPath(new CommitByRevisionOptions { Path = ePath, Timeout = opt.Timeout }); if (item.IsCommit()) { info.Submodule = await commit.GetSubmodule(ePath); } results.Add(info); } finally { concurrencySemaphore.Release(); } })); } await Task.WhenAll(tasks); } return(results.ToList()); }