簡體   English   中英

.NET Real-Time 和 TaskMgr Real-time 優先級類有什么區別?

[英]What's the difference between .NET Real-Time and TaskMgr Real-time priority class?

當我在 .NET 中將進程的優先級設置為實時時:

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

它僅在任務管理器中顯示為“高”優先級:

在此處輸入圖片說明

如果我在任務管理器中手動將其設置為實時,然后再次執行Process.GetCurrentProcess() ,則ProcessPriorityClass仍報告為ProcessPriorityClass.RealTime

如果我以管理員身份運行應用程序,則優先級類確實會更改為實時,如任務管理器所報告的那樣。 所以看起來,當以普通用戶身份運行時,您可以將其設置為RealTime,它會被.NET報告為這樣,但該進程的實際優先級實際上只是High。 為什么 .NET 和 TaskManager 在這種情況下報告不同的值?

真正的罪魁禍首是 Windows。

PriorityClass屬性setter很簡單:

 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 代碼在某些情況下仍然無法工作。 例如,假設您將PriorityClass設置為BelowNormal 如上所述,該值將本地存儲在Process對象中。 然后,如果您再次更改優先級,但從任務管理器中更改,就像之前一樣,.NET 不會意識到它並返回舊值。

如果您絕對需要最新信息,請首先調用process.Refresh()以清除本地存儲的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM