static void WriteStatusLine(StatusLineWriter statusLine, MaxTasks processes, Process currProcess, Stats stats) { currProcess.Refresh(); string statsThreads = String.Join(" | ", currProcess.Threads.Cast <ProcessThread>() .GroupBy(keySelector: t => t.ThreadState) .Select(grp => $"{grp.Key.ToString()} ({(grp.Key == System.Diagnostics.ThreadState.Running ? grp.Count()-1 : grp.Count())})")); string all; string finished; if (stats.AllItems.HasValue) { all = stats.AllItems.ToString(); float ffinished = (float)processes.Done / (float)stats.AllItems.Value; finished = ffinished.ToString("P"); } else { all = "?"; finished = "?"; } statusLine.Write($"running/done/all/finished\t{processes.Running}/{processes.Done}/{all}/{finished}" //+ $"\tthreads: {currProcess.Threads.Count}" + $"\t(forp thread states: {statsThreads})"); }
public static Stats Run(IEnumerable <ProcCtx> ProcessesToStart, TextWriter outStream, TextWriter errStream, int maxParallel, bool skipEmptyLines, bool quiet, bool writeStderr, Func <long> numberJobs) { ProcessRedirectAsync.Init(); Stats stats = new Stats(); if (numberJobs != null) { Task.Run(() => stats.AllItems = numberJobs()); } ICollection <uint> runningProcIDs = new HashSet <uint>(); using (CancellationTokenSource cts = new CancellationTokenSource()) using (TextWriter exitcodeWriter = TextWriter.Synchronized(new StreamWriter(@".\forp.ExitCode.txt", append: false, encoding: Encoding.UTF8))) { log.dbg($"starting with maxParallel: {maxParallel}"); var cancel = cts.Token; if (!quiet) { Console.Error.WriteLine("press 'q' to quit. 'h' for more keys."); } Task.Run(() => HandleKeys(cts, outStream, errStream, runningProcIDs)); var procs = new MaxTasks(); var procsTask = procs.Start( tasks: ProcessesToStart.Select( async(procToRun) => { ProcessStats procStats = await RunOneProcess(procToRun.commandline, procToRun.prefix, outStream, errStream, cancel, skipEmptyLines, writeStderr, runningProcIDs).ConfigureAwait(false); exitcodeWriter.WriteLine($"{procStats.ExitCode}\t{procToRun.commandline}"); Interlocked.Add(ref stats.procTotalTime, procStats.TotalTime.Ticks); Interlocked.Add(ref stats.procKernelTime, procStats.KernelTime.Ticks); Interlocked.Add(ref stats.procUserTime, procStats.UserTime.Ticks); }), MaxParallel: maxParallel, cancel: cts.Token); if (!quiet) { var status = new StatusLineWriter(); var currProcess = Process.GetCurrentProcess(); Misc.DoUntilTaskFinished(procsTask, TimeSpan.FromSeconds(2), () => WriteStatusLine(status, procs, currProcess, stats)); Console.Error.WriteLine(); } else { procsTask.Wait(); } } return(stats); }