async Task <AvalonEditTextOutput> CreateSolution(IEnumerable <LoadedAssembly> assemblies, Language language, CancellationToken ct) { var result = new AvalonEditTextOutput(); var duplicates = new HashSet <string>(); if (assemblies.Any(asm => !duplicates.Add(asm.ShortName))) { result.WriteLine("Duplicate assembly names selected, cannot generate a solution."); return(result); } Stopwatch stopwatch = Stopwatch.StartNew(); try { await Task.Run(() => Parallel.ForEach(assemblies, n => WriteProject(n, language, solutionDirectory, ct))) .ConfigureAwait(false); await Task.Run(() => SolutionCreator.WriteSolutionFile(solutionFilePath, projects)) .ConfigureAwait(false); } catch (AggregateException ae) { if (ae.Flatten().InnerExceptions.All(e => e is OperationCanceledException)) { result.WriteLine(); result.WriteLine("Generation was cancelled."); return(result); } result.WriteLine(); result.WriteLine("Failed to generate the Visual Studio Solution. Errors:"); ae.Handle(e => { result.WriteLine(e.Message); return(true); }); return(result); } foreach (var item in statusOutput) { result.WriteLine(item); } if (statusOutput.Count == 0) { result.WriteLine("Successfully decompiled the following assemblies into Visual Studio projects:"); foreach (var item in assemblies.Select(n => n.Text.ToString())) { result.WriteLine(item); } result.WriteLine(); if (assemblies.Count() == projects.Count) { result.WriteLine("Created the Visual Studio Solution file."); } result.WriteLine(); result.WriteLine("Elapsed time: " + stopwatch.Elapsed.TotalSeconds.ToString("F1") + " seconds."); result.WriteLine(); result.AddButton(null, "Open Explorer", delegate { Process.Start("explorer", "/select,\"" + solutionFilePath + "\""); }); } return(result); }
async Task <AvalonEditTextOutput> CreateSolution(IEnumerable <LoadedAssembly> assemblies, Language language, CancellationToken ct) { var result = new AvalonEditTextOutput(); var duplicates = new HashSet <string>(); if (assemblies.Any(asm => !duplicates.Add(asm.ShortName))) { result.WriteLine("Duplicate assembly names selected, cannot generate a solution."); return(result); } Stopwatch stopwatch = Stopwatch.StartNew(); try { // Explicitly create an enumerable partitioner here to avoid Parallel.ForEach's special cases for lists, // as those seem to use static partitioning which is inefficient if assemblies take differently // long to decompile. await Task.Run(() => Parallel.ForEach(Partitioner.Create(assemblies), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct }, n => WriteProject(n, language, solutionDirectory, ct))) .ConfigureAwait(false); if (projects.Count == 0) { result.WriteLine(); result.WriteLine("Solution could not be created, because none of the selected assemblies could be decompiled into a project."); } else { await Task.Run(() => SolutionCreator.WriteSolutionFile(solutionFilePath, projects)) .ConfigureAwait(false); } } catch (AggregateException ae) { if (ae.Flatten().InnerExceptions.All(e => e is OperationCanceledException)) { result.WriteLine(); result.WriteLine("Generation was cancelled."); return(result); } result.WriteLine(); result.WriteLine("Failed to generate the Visual Studio Solution. Errors:"); ae.Handle(e => { result.WriteLine(e.Message); return(true); }); return(result); } foreach (var item in statusOutput) { result.WriteLine(item); } if (statusOutput.Count == 0) { result.WriteLine("Successfully decompiled the following assemblies into Visual Studio projects:"); foreach (var item in assemblies.Select(n => n.Text.ToString())) { result.WriteLine(item); } result.WriteLine(); if (assemblies.Count() == projects.Count) { result.WriteLine("Created the Visual Studio Solution file."); } result.WriteLine(); result.WriteLine("Elapsed time: " + stopwatch.Elapsed.TotalSeconds.ToString("F1") + " seconds."); result.WriteLine(); result.AddButton(null, "Open Explorer", delegate { Process.Start("explorer", "/select,\"" + solutionFilePath + "\""); }); } return(result); }