.NET Real-Time 和 TaskMgr 实时优先级有什么区别?

当我在 .NET 中将进程的优先级类设置为实时时:

Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

它仅在任务管理器中显示为“高”优先级:

http://img1.mukewang.com/62ca34770001475a07810224.jpg

如果我在任务管理器中手动将其设置为实时,然后Process.GetCurrentProcess()再次执行,ProcessPriorityClass仍然报告为ProcessPriorityClass.RealTime.

如果我以管理员身份运行应用程序,则优先级会更改为实时,正如任务管理器所报告的那样。所以看起来,当以普通用户身份运行时,你可以将其设置为 RealTime,它会被 .NET 报告为这样,但该进程的实际优先级实际上只是 High。为什么在这种情况下 .NET 和 TaskManager 会报告不同的值?


繁星coding
浏览 77回答 1
1回答

慕森卡

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