1 回答

TA貢獻1806條經驗 獲得超8個贊
這里真正的罪魁禍首是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);
}
}
經過幾次健全性檢查后,它調用 Windows API SetPriorityClass,然后檢查返回碼。如果發生錯誤,它會拋出異常。否則,它會在本地存儲新優先級的值(這樣,當您讀取 的值時PriorityClass,它不必調用 Windows 來檢查它)。
在某些情況下,Windows 會拒絕更改優先級(例如,正如您所注意到的,您現在需要管理員權限來設置實時優先級)。訣竅是 Windows默默地拒絕優先級更改并且不返回錯誤代碼。如此處所述:
請注意,即使優先級未設置為 REALTIME_PRIORITY_CLASS,對 SetPriorityClass() 的調用也可能返回成功,因為如果您沒有“增加調度優先級”權限,則對 REALTIME_PRIORITY_CLASS 的請求將被解釋為對允許的最高優先級類的請求當前帳戶。
我猜這樣做是為了避免破壞不希望調用失敗的遺留應用程序。因此,您的 .NET 應用程序不知道優先級更改未按預期工作,并返回錯誤的值。
也就是說,即使 Windows 確實按預期設置了優先級,.NET 代碼在某些情況下仍然無法工作。例如,假設您正在設置PriorityClassto BelowNormal。Process如上所述,該值將本地存儲在對象中。然后,如果您再次更改優先級,但從任務管理器中,就像以前一樣。NET 不會意識到它并返回舊值。
如果您絕對需要最新信息,請先調用process.Refresh()以清除本地存儲的值。
- 1 回答
- 0 關注
- 107 瀏覽
添加回答
舉報