38

I want to execute a command line tool to process data. It does not need to be blocking. I want it to be low priority. So I wrote the below

 Process app = new Process();
 app.StartInfo.FileName = @"bin\convert.exe";
 app.StartInfo.Arguments = TheArgs;
 app.PriorityClass = ProcessPriorityClass.BelowNormal;
 app.Start();

However, I get a System.InvalidOperationException with the message "No process is associated with this object." Why? How do I properly launch this app in low priority?

Without the line app.PriorityClass = ProcessPriorityClass.BelowNormal; the app runs fine.

mafu
  • 28,708
  • 38
  • 138
  • 232

3 Answers3

51

Try setting the PriorityClass AFTER you start the process. Task Manager works this way, allowing you to set priority on a process that is already running.

Robert Harvey
  • 168,684
  • 43
  • 314
  • 475
11

You can create a process with lower priority by doing a little hack. You lower the parent process priority, create the new process and then revert back to the original process priority:

var parent   = Process.GetCurrentProcess();
var original = parent.PriorityClass;

parent.PriorityClass = ProcessPriorityClass.Idle;
var child            = Process.Start("cmd.exe");
parent.PriorityClass = original;

child will have the Idle process priority right at the start.

Pablo Montilla
  • 2,741
  • 1
  • 28
  • 34
  • 2
    That is by far the best solution with no races. The other solutions need to wait until the process is running which can be an issue if you start e.g. a script which starts other child processes which will then run with the initial priority and not the one you will set later. – Alois Kraus Nov 12 '19 at 12:55
5

If you're prepared to P/Invoke to CreateProcess, you can pass CREATE_SUSPENDED in the flags. Then you can tweak the process priority before resuming the process.

Roger Lipscombe
  • 81,986
  • 49
  • 214
  • 348