Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting process instance name from a process id / object (Faster way)

Tags:

c#

Currently, the solution to get a Instance Name from a Process ID is from the code below. Problem is, this takes a lot of time and CPU resources!

That is to say when you have a system that's running at least 100 processes, it takes a considerable amount of time to cycle through the loops to find it. (like 1 to 2 seconds) And when I am looking to find up to 30 of those processes, it takes up to 30 seconds to find them all...

Can't you simply get a instance name from a process object?

private static string GetProcessInstanceName(int pid)
{
  PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");

  string[] instances = cat.GetInstanceNames();
  foreach (string instance in instances)
  {

     using (PerformanceCounter cnt = new PerformanceCounter("Process",  
          "ID Process", instance, true))
     {
        int val = (int) cnt.RawValue;
        if (val == pid)
        {
           return instance;
        }
     }
  }
  throw new Exception("Could not find performance counter " + 
      "instance name for current process. This is truly strange ...");
}
like image 680
ultramoo Avatar asked Mar 29 '26 00:03

ultramoo


2 Answers

The FranzHuber23 Solution sped the original by only looking at processes that start with the process-in-question's name. An improvement beyond that uses PLINQ (parallel LINQ). Optionally, Parallel.ForEach() or a construct that uses Task could provide a similar speedup but both those will have complicated source to return just the first found and cancel the concurrent searches (nicely hidden by ParallelEnumerable.FirstOrDefault()).

public static string PerformanceCounterInstanceName(this Process process)
{
    var matchesProcessId = new Func<string, bool>(instanceName =>
    {
        using (var pc = new PerformanceCounter("Process", "ID Process", instanceName, true))
        {
            if ((int)pc.RawValue == process.Id)
            {
                return true;
            }
        }

        return false;
    });

    string processName = Path.GetFileNameWithoutExtension(process.ProcessName);
    return new PerformanceCounterCategory("Process")
       .GetInstanceNames()
       .AsParallel()
       .FirstOrDefault(instanceName => instanceName.StartsWith(processName)
                                       && matchesProcessId(instanceName));
}
like image 133
mheyman Avatar answered Mar 31 '26 03:03

mheyman


Why not use the System.Diagnostics.Process.GetProcessById function?

private static string GetProcessInstanceName(int pid)
{ 
    string name = String.Empty;
    Process proc = System.Diagnostics.Process.GetProcessById(pid);
    if(proc != null)
    {
        name = proc.ProcessName;
    }
    return name;
}
like image 26
Avi Turner Avatar answered Mar 31 '26 04:03

Avi Turner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!