Itamar Levy
Itamar Levy

Reputation: 93

How do I measure child process launch time in c#?

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

Answers (1)

Ofir Winegarten
Ofir Winegarten

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

Related Questions