How can I/O priority of a process be increased?

The relevant information seems to be a bit scattered compared to the usual MS documentation. There is this white paper that discusses I/O Prioritization in windows. This doc seems to have beta flags all over it but I guess it's probably mostly pretty accurate.

Two important things to note:

  1. You can only reduce the priority of IO requests below normal.
  2. The driver can ignore any such request and treat it as normal anyway.

The useful APIs for client applications are SetFileInformationByHandle:

FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;
result = SetFileInformationByHandle( hFile,
                                     FileIoPriorityHintInfo,
                                     &priorityHint,
                                     sizeof(PriorityHint));

SetPriorityClass:

// reduce CPU, page and IO priority for the whole process
result = SetPriorityClass( GetCurrentProcess(),
                           PROCESS_MODE_BACKGROUND_BEGIN);
// do stuff
result = SetPriorityClass( GetCurrentProcess(),
                           PROCESS_MODE_BACKGROUND_END);

SetThreadPriority which is similar:

// reduce CPU, page and IO priority for the current thread
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
// do stuff
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

SetFileBandwithReservation:

// reserve bandwidth of 200 bytes/sec
result = SetFileBandwidthReservation( hFile,
                                  1000,
                                  200,
                                  FALSE,
                                  &transferSize,
                                  &outstandingRequests );

For .Net do the usual stuff with P/Invoke.


It looks like the "real" way to set the IO priority of a process is using NtSetInformationProcess with the ProcessIoPriority information class. Unfortunately this API is undocumented, but you can see it in action by attaching a debugger to taskeng.exe and breaking in ExeTask::GetYourPrioritiesStraight.

I believe the PROCESS_INFORMATION_CLASS value for ProcessIoPriority is 33 (0x21), and the priority values are as follows:

Very Low: 0
Low: 1
Normal: 2
High: 3 or above?

The values above are a best-guess based on what I can tell from the debugger; the task scheduler seems to use a value of 1 for tasks with priority 7, and a value of 2 for tasks with priority 5 (see this question and this MSDN article for more on task scheduler priorities). Calling SetPriorityClass with PROCESS_MODE_BACKGROUND_BEGIN uses a value of 0.

I have unfortunately not found any public API that can be used for this, other than the SetPriorityClass method in @1800 INFORMATION's answer, which sets the priority to Very Low.

Edit: I've written a utility that can be used to query or set the IO prority of a process, available here.