Reputation: 93
How do I measure child process launch time in c#? I am currently using the following code to measure executable launch time and would like to add child process execution launch time, for example CMD running notepad or new tab in Chrome.
Here is my existing code for measuring "normal" process launch time:
public static long LaunchProcess(String processFullPath)
{
Process process;
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
process = Process.Start(processFullPath);
process.WaitForInputIdle();
watch.Stop();
etc....
Any help or direction will be highly appreciated!
Upvotes: 3
Views: 288
Reputation: 9365
So the trick is first to detect all child processes:
var mos = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={process.Id}");
Then, we can collect them in loop and start a new Task
to measure the execution time. At the end loop through Task
list and print the elapsed time.
public Tuple<int, TimeSpan> MonitorProcess(Process process)
{
Stopwatch stopwatch = Stopwatch.StartNew();
process.WaitForExit();
stopwatch.Stop();
return Tuple.Create(process.Id, stopwatch.Elapsed);
}
public void LaunchProcess(String processFullPath)
{
try
{
var tasks = new List<Task<Tuple<int,TimeSpan>>>();
Process process = Process.Start(processFullPath);
if (process == null) return;
// Add my current (parent) process
tasks.Add(Task.Factory.StartNew(()=>this.MonitorProcess(process)));
var childProcesses = new List<Process>();
while (!process.HasExited)
{
// Find new child-processes
var mos = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={process.Id}");
List<Process> newChildren = mos.Get().Cast<ManagementObject>().Select(mo => new { PID = Convert.ToInt32(mo["ProcessID"]) })
.Where(p => !childProcesses.Exists(cp => cp.Id == p.PID)).Select(p => Process.GetProcessById(p.PID)).ToList();
// measure their execution time in different task
tasks.AddRange(newChildren.Select(newChild => Task.Factory.StartNew(() => this.MonitorProcess(newChild))));
childProcesses.AddRange(newChildren);
}
// Print the results
StringBuilder sb = new StringBuilder();
foreach (Task<Tuple<int, TimeSpan>> task in tasks) {
sb.AppendLine($"[{task.Result.Item1}] - {task.Result.Item2}");
}
this.output.WriteLine(sb.ToString());
}
catch (Exception ex)
{
}
}
Upvotes: 1