C # CPU Kullanımı Nasıl Alınır?


Yanıtlar:


205

Sen kullanabilirsiniz PerformanceCounter gelen sınıf System.Diagnostics .

Bu şekilde başlat:

PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;

cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");

Bunun gibi tüketin:

public string getCurrentCpuUsage(){
            return cpuCounter.NextValue()+"%";
}

public string getAvailableRAM(){
            return ramCounter.NextValue()+"MB";
} 

80
Güzel - ancak orijinal kaynak buradan geliyor gibi görünüyor: zamov.online.fr/EXHTML/CSharp/CSharp_927308.html
Matt Refghi

19
Ne keşfettiğimden iki kez cpuCounter.NextValue () kullanmak zorunda kaldım ve aralarında Uyku (500)
Angel.King.47

Matt haklı. "Dönüş" anahtar kelimesini unutmak gibi hataları da dahil.
Mark At Ramp51

8
evet, o bağlantıdan bir kopya gibi görünüyor, bu yüzden orijinal referans için bir bağlantı güzel bir stil olurdu. Öte yandan, burada cevap vermek için CMS'nin hoş yanı da tembel geliştiricilerin aynı cevabı bulmak için tüm Google'da arama yapmaları gerekmiyor. : o)
BerggreenDK

13
Bir System.Threading.Thread.Sleep aradaki (1000 ms yeterli olmalıdır) ile .NextValue öğesini iki kez çağırmanız gerekecektir. Bunun neden gerekli olduğu hakkında daha fazla bilgi için blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx adresine bakın , ancak üst düzey özet, değeri hesaplamak için iki örneğe ihtiyacınız olduğu, ve her ikisini de almak için işletim sistemine bir süre vermeniz gerekir.
Cleggy

63

Biraz daha fazla requsted ama CPU kullanımı 1 dakika veya daha uzun bir süre boyunca% 90 veya daha yüksek olup olmadığını izlemek ve uyarmak için ekstra zamanlayıcı kodu kullanın.

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";
    }
}

7
GetRAMCounter () nerede?
Dieter B

2
cpuCounter.NextValuedöndürür afloat . Öyleyse neden a dynamic? Öyleyse neden bunu dynamicbir object? Öyleyse neden objectbir intsatırda bir an atamaya çalışalım int cpuPercent = getCPUCounter()? (Bu kod derlenmeyecektir.)
Wyck

21

Oldukça karmaşık görünen birkaç farklı parçayı okumak için biraz zaman geçirdikten sonra bununla geldim. SQL Server'ı izlemek istediğim 8 çekirdekli bir makineye ihtiyacım vardı. Aşağıdaki kod için "sqlservr" appName olarak geçti.

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 çekirdek sunucumda SQL tarafından kullanılan CPU yüzdesini doğru bir şekilde ölçüyor gibi görünüyor.


total_cpu PerformanceCounter ("Process") değil PerformanceCounter ("Processor") olmalıdır. Aksi takdirde sadece% 100 * çekirdek sayısı elde edersiniz.
steve cook

3
Nerede doğruya ayarlıyorsunuz done? Ben bir şey göz ardı sürece, bu sonsuz bir döngü gibi görünüyor:while(!done){...}
Manfred

@Manfred Gerçekten sonsuz bir döngü
Jenny

16

Tamam, anladım! Yardımınız için teşekkürler!

İşte bunu yapmak için kod:

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;
}

SelectedServer değişkeni yerine alma sunucu adı eklemek daha iyiydi. like this.string computername = Çevre.GetEnvironmentVariable ("bilgisayaradı");
Dave


5

CMS doğru var, ama aynı zamanda sunucu gezginini görsel stüdyoda kullanır ve performans sayacı sekmesiyle oynarsanız, çok sayıda yararlı metriği nasıl elde edeceğinizi anlayabilirsiniz.


3

Bu benim için işe yarıyor gibi görünüyor, işlemci belli bir yüzdeye ulaşana kadar beklemeye bir örnek

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();
}

kullanım 0 olduğunda neden uyuyorsun?
watashiSHUN

2

Bu sınıf sayacı her 1 saniyede bir otomatik olarak yoklar ve ayrıca iş parçacığı için güvenlidir:

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.DateTimeaslında 8 baytlık bir değer türüdür, yani bir DateTimedeğişkene atamalar atomik değildir. Bu kod 32 bit platformlarda iş parçacığı için güvenli değildir.
andrewjs

1

Tüm PerformanceCounterçözümlere 1 saniyelik durak eklemek zorunda kalmadım . Bunun yerine bir WMIçözüm kullanmayı seçtim . 1 saniyelik bekleme / duraklamanın nedeni, a değerini kullanırken okunan değerin doğru olmasını sağlamaktır PerformanceCounter. Ancak, bu yöntemi sık sık çağırıyor ve bu bilgileri yeniliyorsanız, sürekli olarak bu gecikmeye maruz kalmamanızı tavsiye ederim ... bunu almak için zaman uyumsuz bir işlem yapmayı düşünseniz bile.

Buradan snippet ile başladım C # kullanarak WMI'da CPU kullanımı döndürme ve aşağıdaki blog yazımda çözümün tam bir açıklaması eklendi:

WMI Kullanarak C # İçindeki Tüm Çekirdekler Üzerinde CPU Kullanımı Alın


Lütfen blogunuza bağlantı vermek yerine yanıtı buraya ekleyin.
Herman

@Herman - Sadece bloguma bağlantı vermedim; Bir açıklama yaptım ve buradaki mesajın ötesinde derin bir cevap için bir bağlantı sağlamaya devam ettim.
atconway

blog yazınızdaki çözüm 12 satırlık kod gibidir. İnsanları blogunuzu ziyaret etmeye çalışmaktan başka neden cevabınıza eklemiyorsunuz?
Herman

@Herman - Derinlemesine bir açıklama içerdiğinden bağlantıya tıklamanın sorunu nedir; 'neden' bölümünün hazırlanması fikri bu mu? Ayrıca bu sadece 7 yaşında. Bu tam gönderiyi hatırlamak zor ve o zamanlar SO'da bir yeniliğim.
atconway

bağlantı kopabilir ve temel içerik satır içi olduğunda yanıtları taramak çok daha kolaydır. Diğer cevabımda sert olduğum için üzgünüm, size zor zaman vermek için burada değilim. :)
Herman

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.