internal string PrintCriticalPath( NodeAndCriticalPath nodeAndCriticalPath, GetElapsedLookup getElapsed, GetKernelTimeLookup getKernelTime, GetUserTimeLookup getUserTime, GetCriticalPathLookup getCriticalPath, out Model.CriticalPath criticalPath) { Contract.Assert(getElapsed != null, "getElapsed must be set."); Contract.Assert(getCriticalPath != null, "getCriticalPath must be set."); Contract.Assert(!nodeAndCriticalPath.Equals(default(NodeAndCriticalPath)), "nodeAndCriticalPath must be set."); criticalPath = new Model.CriticalPath(); ConcurrentDictionary <PathAtom, TimeSpan> toolStats = new ConcurrentDictionary <PathAtom, TimeSpan>(); var totalTimeWidth = ToSeconds(nodeAndCriticalPath.Time).Length; var totalKernelTimeWidth = ToSeconds(nodeAndCriticalPath.KernelTime).Length; var totalUserTimeWidth = ToSeconds(nodeAndCriticalPath.UserTime).Length; criticalPath.time = ToSeconds(nodeAndCriticalPath.Time); TimeSpan startTime = new TimeSpan(0); using (var output = new StringWriter(CultureInfo.InvariantCulture)) { using (var criticalPathWriter = new StringWriter(CultureInfo.InvariantCulture)) { while (true) { var pip = CachedGraph.PipGraph.GetPipFromUInt32(nodeAndCriticalPath.Node.Value); var process = pip as Process; var elapsed = getElapsed(nodeAndCriticalPath.Node); var kernelTime = getKernelTime(nodeAndCriticalPath.Node); var userTime = getUserTime(nodeAndCriticalPath.Node); if (process != null) { toolStats.AddOrUpdate(process.GetToolName(CachedGraph.Context.PathTable), elapsed, (k, v) => v + elapsed); } var node = new Node(); node.pipId = pip.PipId.Value.ToString("X16", CultureInfo.InvariantCulture).TrimStart(new Char[] { '0' }); node.semiStableHash = pip.SemiStableHash.ToString("X"); node.pipType = pip.PipType.ToString(); node.duration = ToSeconds(elapsed); node.kernelTime = ToSeconds(kernelTime); node.userTime = ToSeconds(userTime); node.shortDescription = pip.GetShortDescription(CachedGraph.Context); node.startTime = ToSeconds(startTime); startTime = startTime + elapsed; criticalPath.nodes.Add(node); criticalPathWriter.Write( "({0}) ({2}) ({3}) [{1}]", ToSeconds(elapsed).PadLeft(totalTimeWidth), pip.GetDescription(CachedGraph.Context), ToSeconds(kernelTime).PadLeft(totalKernelTimeWidth), ToSeconds(userTime).PadLeft(totalUserTimeWidth)); if (nodeAndCriticalPath.Next.IsValid) { criticalPathWriter.WriteLine(" =>"); } else { criticalPathWriter.WriteLine(); break; } nodeAndCriticalPath = getCriticalPath(nodeAndCriticalPath.Next); } output.WriteLine("TOOL STATS:"); foreach (var toolStatEntry in toolStats.OrderByDescending(kvp => kvp.Value)) { output.WriteLine( "{0}, {1}", ToSeconds(toolStatEntry.Value).PadLeft(totalTimeWidth), toolStatEntry.Key.ToString(CachedGraph.Context.StringTable)); var toolStat = new ToolStat(); toolStat.name = toolStatEntry.Key.ToString(CachedGraph.Context.StringTable); toolStat.time = ToSeconds(toolStatEntry.Value); criticalPath.toolStats.Add(toolStat); } output.WriteLine(); output.WriteLine("( Duration ) ( Kernel Time ) ( User Time ) Seconds :: CRITICAL PATH DEPENDENCY LIST:"); output.Write(criticalPathWriter.ToString()); } return(output.ToString()); } }