真正的罪魁祸首是Windows。
该
安装者
PriorityClass
属性
很简单:
set {
if (!Enum.IsDefined(typeof(ProcessPriorityClass), value)) {
throw new InvalidEnumArgumentException(“value”, (int)value, typeof(ProcessPriorityClass));
}
// BelowNormal and AboveNormal are only available on Win2k and greater.
if (((value & (ProcessPriorityClass.BelowNormal | ProcessPriorityClass.AboveNormal)) != 0) &&
(OperatingSystem.Platform != PlatformID.Win32NT || OperatingSystem.Version.Major < 5)) {
throw new PlatformNotSupportedException(SR.GetString(SR.PriorityClassNotSupported), null);
}
SafeProcessHandle handle = null;
try {
handle = GetProcessHandle(NativeMethods.PROCESS_SET_INFORMATION);
if (!NativeMethods.SetPriorityClass(handle, (int)value)) {
throw new Win32Exception();
}
priorityClass = value;
havePriorityClass = true;
}
finally {
ReleaseProcessHandle(handle);
}
}
</code>
经过一些完整性检查后,它会调用Windows API
SetPriorityClass
,然后检查返回码。如果发生错误,则会引发异常。否则,它会在本地存储新优先级的值(这样,当您读取值时)
PriorityClass
,它不必调用Windows来检查它)。
在某些情况下,Windows将拒绝更改优先级(例如,正如您所注意到的,您现在需要管理员权限来设置实时优先级)。诀窍是Windows
的
以静默方式拒绝优先级更改,并且不返回错误代码
</强>
。如记录
这里
:
请注意,即使优先级未设置为REALTIME_PRIORITY_CLASS,对SetPriorityClass()的调用也可能返回成功,因为如果您没有“增加调度优先级”权限,则对REALTIME_PRIORITY_CLASS的请求将被解释为对允许的最高优先级类别的请求经常账户。
我猜这是为了避免破坏那些不希望他们的调用失败的遗留应用程序。因此,您的.NET应用程序不知道优先级更改未按预期工作,并返回错误的值。
也就是说,即使Windows确实按预期设置了优先级,.NET代码在某些情况下仍然无效。例如,假设你正在设置
PriorityClass
至
BelowNormal
。该值将存储在本地
Process
对象,如上所述。然后,如果您再次从任务管理器更改优先级,就像.NET之前不会知道它并返回旧值。
如果您绝对需要最新信息,请先致电
process.Refresh()
清除本地存储的值。