I want to increase the I/O priority of a process. Answers for both .NET and Windows Vista would be nice. processexplorer is ok as well.
相关问题
- Generic Generics in Managed C++
- How to Debug/Register a Permanent WMI Event Which
- 'System.Threading.ThreadAbortException' in
- Bulk update SQL Server C#
- Should I use static function in c# where many call
Be sure to align
FILE_IO_PRIORITY_HINT_INFO
structure properly when callingSetFileInformationByHandle
.Otherwise, you will get a
ERROR_NOACCESS
(error 998, 0x000003E6).Just an update for this - it can all be done via .NET without resorting to WinAPI ...
I've tried the above setting the process priority in a WPF application and it works fine. Haven't needed to set thread priority.
EDIT: this above relates to CPU priority of a process, as opposed to I/O priority, however there may be some correlation / connection between a process's CPU priority and its I/O priority.
It looks like the "real" way to set the IO priority of a process is using
NtSetInformationProcess
with theProcessIoPriority
information class. Unfortunately this API is undocumented, but you can see it in action by attaching a debugger to taskeng.exe and breaking inExeTask::GetYourPrioritiesStraight
.I believe the
PROCESS_INFORMATION_CLASS
value forProcessIoPriority
is 33 (0x21), and the priority values are as follows: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
withPROCESS_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.
The proper way to do this is to call SetProcessPriorityClass with PROCESS_BACKGROUND_MODE_BEGIN to initiate a background mode. This causes a Very Low (background) I/O priority and Idle CPU priority. When done, call SetProcessPriorityClass again, supplying PROCESS_BACKGROUND_MODE_END. The same can be done at the thread level via SetThreadPriority and THREAD_BACKGROUND_MODE_BEGIN/END.
If you want to directly set the I/O priority, independently of the CPU priority, you must use the NT native APIs. I documented it here, but did not include code examples as we all know they get ripped verbatim.
The API you want is the NT Native API NtSetInformationProcess. Using this API you can change the I/O priority. This API accepts a 'class' variable telling it what type of information about the process you want to change, that class variable must be set to ProcessIoPriority. You can then set the entire process's I/O priority in this manner.
Similarly, the I/O priority can be retrieved via NtQueryInformationProcess.
The bad news is that the priority levels are a bit limited. Critical is reserved for system paging operations. That leaves you with Normal and Very Low (Background). Low and High may or may not be implemented in newer editions of Windows. There seems to be partial support, at the very least.
If you have no experience with the NT Native APIs, the first thing to do is understand them. Once you do, you'll see it is as simple as a single API call.
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:
The useful APIs for client applications are SetFileInformationByHandle:
SetPriorityClass:
SetThreadPriority which is similar:
SetFileBandwithReservation:
For .Net do the usual stuff with P/Invoke.