【C#】PerformanceCounterでCPU使用率を取得しようとしたら失敗した

Post : 2023/6/4 Update : 2023/12/3

C#でCPUの使用率を取得しようとしたらすんなりいかなかったので備忘録として。

https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.performancecounter?view=dotnet-plat-ext-7.0

C#でCPUの使用率を取得したい場合PerformanceCounterを初期化するとき文字列で(カテゴリ名,カウンタ名,インスタンス名)を渡して初期化する。

調べるとCPUの使用率はこんな感じで取得できるという情報が出てくる


//カテゴリ名, カウンタ名, インスタンス名を指定してインスタンスを作成
PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");

//カウンタの値を取得(0~1)
var percent = pc.NextValue() / 100.0f;
//パーセント(%)で表示
Console.WriteLine("{0,8:P2}", percent);

なんかタスクマネージャーと値を見比べるとなんか違う。

解決方法

どうもカテゴリ名にはProcessorProcessor Informationがあるみたい

詳しくは調べてないがProcessor Informatioの方が後発らしくProcessorはCPUのコア数が64コア以上や

https://jpwinsup.github.io/blog/2022/07/15/Performance/SystemResource/PerformanceCounterProcessor/#:~:text=Processor%20%E3%81%AF%E3%80%81%E4%BB%A5%E5%89%8D%E3%81%8B%E3%82%89%E4%BD%BF%E7%94%A8,%E3%81%95%E3%82%8C%E3%81%9F%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%20%E3%82%AB%E3%82%A6%E3%83%B3%E3%82%BF%E3%83%BC%E3%81%A7%E3%81%99%E3%80%82

ということでカテゴリ名をProcessor Information、カウンタ名をUtilityに変更することでタスクマネージャーとの値を取得できた。

static void Main(string[] args)
{
    System.Diagnostics.PerformanceCounter cpuCounter = new System.Diagnostics.PerformanceCounter("Processor Information", "% Processor Utility","_Total");

    while (true)
    {
        Console.WriteLine(cpuCounter.NextValue() / 100.0f);
        if (Console.KeyAvailable) break;
        System.Threading.Thread.Sleep(1000);
    }
}

Unityでは失敗

ちなみUnityで同様のコードを書いても正しく取得はできなかった。

var performanceCounterCategories = System.Diagnostics.PerformanceCounterCategory.GetCategories();

foreach (System.Diagnostics.PerformanceCounterCategory performanceCounterCategory in performanceCounterCategories)
{
    Debug.Log(performanceCounterCategory.CategoryName);
 }

上のような形でカテゴリ名一覧を取得してもPerformance Informationが含まれていなかったため、おそらくUntiyのPerformanceCounter.dllが微妙に違うからだと思う。

【2023/12/03追記】

C++でDLLを作成してUnityからアクセスできるようにしてみた