C#でアプリケーションの全体的な合計CPU使用率を取得したいと考えています。プロセスのプロパティを詳しく調べる方法はたくさんありますが、必要なのは、プロセスのCPU使用率と、TaskManagerで得られるような合計CPUだけです。
それ、どうやったら出来るの?
C#でアプリケーションの全体的な合計CPU使用率を取得したいと考えています。プロセスのプロパティを詳しく調べる方法はたくさんありますが、必要なのは、プロセスのCPU使用率と、TaskManagerで得られるような合計CPUだけです。
それ、どうやったら出来るの?
回答:
System.DiagnosticsのPerformanceCounterクラスを使用できます。
このように初期化します:
PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
このように消費します:
public string getCurrentCpuUsage(){
return cpuCounter.NextValue()+"%";
}
public string getAvailableRAM(){
return ramCounter.NextValue()+"MB";
}
要求されたものより少し多いですが、追加のタイマーコードを使用して、CPU使用率が1分以上継続して90%以上かどうかを追跡して警告します。
public class Form1
{
int totalHits = 0;
public object getCPUCounter()
{
PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
// will always start at 0
dynamic firstValue = cpuCounter.NextValue();
System.Threading.Thread.Sleep(1000);
// now matches task manager reading
dynamic secondValue = cpuCounter.NextValue();
return secondValue;
}
private void Timer1_Tick(Object sender, EventArgs e)
{
int cpuPercent = (int)getCPUCounter();
if (cpuPercent >= 90)
{
totalHits = totalHits + 1;
if (totalHits == 60)
{
Interaction.MsgBox("ALERT 90% usage for 1 minute");
totalHits = 0;
}
}
else
{
totalHits = 0;
}
Label1.Text = cpuPercent + " % CPU";
//Label2.Text = getRAMCounter() + " RAM Free";
Label3.Text = totalHits + " seconds over 20% usage";
}
}
cpuCounter.NextValue
を返しますfloat
。それで、なぜそれをaに割り当てるのdynamic
ですか?次に、それをなぜとして返すdynamic
のobject
ですか?なぜ割り当てようとobject
するint
ラインでint cpuPercent = getCPUCounter()
?(そのコードはコンパイルされません。)
かなり複雑に思えたいくつかの異なるスレッドを読んでしばらく時間を費やした後、私はこれを思いつきました。SQLサーバーを監視したい8コアマシンに必要でした。以下のコードでは、「sqlservr」をappNameとして渡しました。
private static void RunTest(string appName)
{
bool done = false;
PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total");
PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", appName);
while (!done)
{
float t = total_cpu.NextValue();
float p = process_cpu.NextValue();
Console.WriteLine(String.Format("_Total = {0} App = {1} {2}%\n", t, p, p / t * 100));
System.Threading.Thread.Sleep(1000);
}
}
8コアサーバーでSQLによって使用されているCPUの割合を正しく測定しているようです。
done
にtrue を設定しますか?私が何かを見落としたのでない限り、これは無限ループのようです:while(!done){...}
大丈夫、わかった!ご協力いただきありがとうございます!
これを行うコードは次のとおりです。
private void button1_Click(object sender, EventArgs e)
{
selectedServer = "JS000943";
listBox1.Items.Add(GetProcessorIdleTime(selectedServer).ToString());
}
private static int GetProcessorIdleTime(string selectedServer)
{
try
{
var searcher = new
ManagementObjectSearcher
(@"\\"+ selectedServer +@"\root\CIMV2",
"SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name=\"_Total\"");
ManagementObjectCollection collection = searcher.Get();
ManagementObject queryObj = collection.Cast<ManagementObject>().First();
return Convert.ToInt32(queryObj["PercentIdleTime"]);
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
return -1;
}
WMIを使用して、CPUのパーセンテージ情報を取得できます。適切な権限があれば、リモートコンピュータにログインすることもできます。http://www.csharphelp.com/archives2/archive334.htmlを見て、達成できることのアイデアを得てください。
Win32_Process名前空間のMSDNリファレンスも参考になります。
CodeProjectの例も参照してくださいC#を経由して(ほぼ)すべてでWMI:どのようにするに。
これは私にとってはうまくいくようです、プロセッサが特定の割合に達するまで待つ例
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
int usage = (int) cpuCounter.NextValue();
while (usage == 0 || usage > 80)
{
Thread.Sleep(250);
usage = (int)cpuCounter.NextValue();
}
このクラスは1秒ごとに自動的にカウンターをポーリングし、スレッドセーフでもあります。
public class ProcessorUsage
{
const float sampleFrequencyMillis = 1000;
protected object syncLock = new object();
protected PerformanceCounter counter;
protected float lastSample;
protected DateTime lastSampleTime;
/// <summary>
///
/// </summary>
public ProcessorUsage()
{
this.counter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public float GetCurrentValue()
{
if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
{
lock (syncLock)
{
if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
{
lastSample = counter.NextValue();
lastSampleTime = DateTime.UtcNow;
}
}
}
return lastSample;
}
}
System.DateTime
実際には8バイトの値タイプです。つまり、DateTime
変数への割り当てはアトミックではありません。このコードは、32ビットプラットフォームではスレッドセーフではありません。
すべてのPerformanceCounter
ソリューションに1秒のストールを追加する必要がありませんでした。代わりに、WMI
ソリューションを使用することにしました。1秒の待機/ストールが存在する理由は、を使用するときに読み取り値を正確にするためPerformanceCounter
です。ただし、このメソッドを頻繁に呼び出してこの情報を更新する場合は、それを取得するために非同期プロセスを実行することを考えていても、その遅延を常に発生させないようにしてください。
私はここからスニペットを開始し、C#を使用してWMIでCPU使用率を返すと、以下のブログ投稿にソリューションの完全な説明を追加しました。
public int GetCpuUsage()
{
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", Environment.MachineName);
cpuCounter.NextValue();
System.Threading.Thread.Sleep(1000); //This avoid that answer always 0
return (int)cpuCounter.NextValue();
}
このリンクの元の情報https://gavindraper.com/2011/03/01/retrieving-accurate-cpu-usage-in-c/