プロセスの実行中にRAMメモリとCPU使用率を取得する必要があります(プロセスは30分以上実行される場合があります)。無料でRAM=を取得できますが、タスクマネージャーの値と比較して、CPU使用率が正しくありません。何か問題がありますか?これが私のコードです。
class Program
{
static List<float> AvailableCPU = new List<float>();
static List<float> AvailableRAM = new List<float>();
protected static PerformanceCounter cpuCounter;
protected static PerformanceCounter ramCounter;
static void Main(string[] args)
{
cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
try
{
System.Timers.Timer t = new System.Timers.Timer(1200);
t.Elapsed += new ElapsedEventHandler(TimerElapsed);
t.Start();
Thread.Sleep(10000);
}
catch (Exception e)
{
Console.WriteLine("catched exception");
}
Console.ReadLine();
}
public static void TimerElapsed(object source, ElapsedEventArgs e)
{
float cpu = cpuCounter.NextValue();
float ram = ramCounter.NextValue();
Console.WriteLine(string.Format("CPU Value: {0}, ram value: {1}", cpu, ram));
AvailableCPU.Add(cpu);
AvailableRAM.Add(ram);
}
}
しかし、プログラムを実行すると、タスクマネージャーの値と比較して、コンソールに出力されたものが次のようになります。
何が悪いのですか?
あなたの価値観に問題はありません。
タスクマネージャーが返す内容との違いが見られる理由は、「CPU使用率」の値が計算されたものであるためです特定の間隔で、つまり2つのNextValue()
呼び出しの間。タスクマネージャーが "それ自体のNextValueを呼び出さない"場合(機能を単純化する場合)、それと同時に、同じ結果が返されません。
次のシナリオを想像してみてください。
Time 0: 0% actual CPU usage
Time 1: 50% actual CPU usage
Time 2: 70% actual CPU usage
Time 3: 2% actual CPU usage
Time 4: 100% actual CPU usage
独自のアプリケーションの複数のプロセスを生成しようとすることもできますが、異なる結果が表示されるはずです。
これが私が見つけたものです:各コアのPerformanceCounter
オブジェクトを含むリストを作成し、パーセントを追加して、結果を物理コアの数で割ります:
class Program
{
static List<float> AvailableCPU = new List<float>();
static List<float> AvailableRAM = new List<float>();
protected static PerformanceCounter cpuCounter;
protected static PerformanceCounter ramCounter;
static List<PerformanceCounter> cpuCounters = new List<PerformanceCounter>();
static int cores = 0;
static void Main(string[] args)
{
cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
{
cores = cores + int.Parse(item["NumberOfCores"].ToString());
}
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
int procCount = System.Environment.ProcessorCount;
for(int i = 0; i < procCount; i++)
{
System.Diagnostics.PerformanceCounter pc = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", i.ToString());
cpuCounters.Add(pc);
}
Thread c = new Thread(ConsumeCPU);
c.IsBackground = true;
c.Start();
try
{
System.Timers.Timer t = new System.Timers.Timer(1200);
t.Elapsed += new ElapsedEventHandler(TimerElapsed);
t.Start();
Thread.Sleep(10000);
}
catch (Exception e)
{
Console.WriteLine("catched exception");
}
Console.ReadLine();
}
public static void ConsumeCPU()
{
int percentage = 60;
if (percentage < 0 || percentage > 100)
throw new ArgumentException("percentage");
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
}
public static void TimerElapsed(object source, ElapsedEventArgs e)
{
float cpu = cpuCounter.NextValue();
float sum = 0;
foreach(PerformanceCounter c in cpuCounters)
{
sum = sum + c.NextValue();
}
sum = sum / (cores);
float ram = ramCounter.NextValue();
Console.WriteLine(string.Format("CPU Value 1: {0}, cpu value 2: {1} ,ram value: {2}", sum, cpu, ram));
AvailableCPU.Add(sum);
AvailableRAM.Add(ram);
}
}
これが結果のスクリーンショットです(ご覧のとおり、最初の方法の方が正確です)。