15

このクラスを、プロセスを起動して何らかの入力を与え、プロセスがアイドル状態になるのを待ってからさらに入力を与えるテストのカテゴリの基本クラスとして使用しています。

public abstract class TestProcessLaunchingBase
{
    protected PerformanceCounter PerfCounter { get; set; }

    protected void WaitForProcessIdle()
    {
        while (true)
        {
            float oldValue = PerfCounter.NextValue();

            Thread.Sleep(1000);

            float nextValue = PerfCounter.NextValue();

            if (nextValue == 0)
                break;
        }
    }

    protected void FindSpawnedProcessPerfCounter(int processId)
    {
        PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
        string[] instances = cat.GetInstanceNames();
        foreach (string instance in instances)
        {
            using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process", instance, true))
            {
                int val = (int)cnt.RawValue;
                if (val == processId)
                {
                    PerfCounter = new PerformanceCounter("Process", "% Processor Time", instance);
                    break;
                }
            }

        }

        Assert.IsNotNull(PerfCounter, "Failed to perf counter");
    }
}

これらのテストは失敗することPerfCounter.NextValue()があります。

System.InvalidOperationException インスタンス 'foobar#2' は指定されたカテゴリに存在しません

パフォーマンス カウンターのインスタンス名が永続的ではないようです。

3 つの foobar プロセスがある場合、インスタンス名を持つ可能性があります

  • フーバー pid 5331
  • foob​​ar #1 pid 5332
  • foob​​ar #2 pid 5333

pid 5332がfoobar #2を出るとfoobar #1になるようです。

質問:

  1. これは文書化された動作ですか? パフォーマンス カウンターを永続化できませんか? 毎回調べないといけないの?

  2. または、 foobarという名前のすべてのプロセスのプロセッサー時間を提供できるパフォーマンス カウンターはありますか

4

2 に答える 2

9

私はすでに過去にこの問題に直面しました。インスタンス名のProcessName#InstanceNumberパターンは明らかに Microsoft の不適切な選択でした。その理由はご存じの通りです :)

したがって、基本的には次の 2 つの選択肢があります。

PerformanceCounter1) メソッドを使用して、毎回新しいインスタンスを作成しますFindSpawnedProcessPerfCounter

2) KB281884に記載されている手順に従って、パターンを から に変更ProcessName#InstanceNumberProcessName_ProcessIDます。

最初の解決策の問題は、毎回新しいインスタンスを構築するのにいくらかの CPU 時間が必要になることです。

2 番目の解決策の問題は、レジストリの変更が、このパフォーマンス カウンターを使用しているすべてのプログラムにも影響を与えることです。また、アプリを起動する前にレジストリを変更する必要があります。

最後のオプションは、パフォーマンス カウンターをまったく使用しないことです。情報だけに関心がある場合は、ProcessorTimeP/Invoke を使用して呼び出して取得できる Kernel32 関数がいくつかあります。

編集:

このProcessクラスはUserProcessorTime、およびPrivilegedProcessorTime(カーネル プロセッサ時間) プロパティも提供します。TimeSpanどちらもインスタンス (= 時間) を返すため、プロセッサ時間の割合を取得するには、自分で計算を行う必要があります (更新期間とプロセッサ時間を含む)。

于 2012-08-13T17:22:38.290 に答える