2008-11-10 7 views
159

Я хочу получить общее общее использование ЦП для приложения на C#. Я нашел много способов вникать в свойства процессов, но мне нужно только процессорное использование процессов и общий процессор, как вы получаете в TaskManager.Как получить использование ЦП в C#?

Как это сделать?

+1

http://stackoverflow.com/questions/4679962/what-is-the-correct-performance-counter-to-get-cpu-and-memory-usage-of-a-process/4680030 # 4680030 – SwDevMan81

ответ

167

Вы можете использовать класс PerformanceCounter от System.Diagnostics.

Initialize так:

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

Nice - но th Первоначальный источник выглядит отсюда: http://zamov.online.fr/EXHTML/CSharp/CSharp_927308.html –

+15

Из того, что я обнаружил, мне пришлось использовать cpuCounter.NextValue() дважды, и между ними мне пришлось спать (500) –

+0

Мэтт прав. Даже включая ошибки, такие как забывание ключевого слова «возврат». –

5

CMS имеет это право, но если вы используете исследователь сервера в визуальной студии и играть с вкладки счетчика производительности то вы можете выяснить, как получить множество полезных показателей.

9

Вы можете использовать WMI для получения информации о процентах процессора. Вы можете даже войти на удаленный компьютер, если у вас есть правильные разрешения. Посмотрите на http://www.csharphelp.com/archives2/archive334.html, чтобы получить представление о том, что вы можете выполнить.

Также полезно использовать ссылку MSDN для пространства имен Win32_Process.

См. Также пример CodeProject How To: (Almost) Everything In WMI via C#.

13

Всё нормально, я понял! Спасибо за вашу помощь!

Вот код, чтобы сделать это:

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 = 
      ManagementObjectSearcher 
      (@"\\"+ selectedServer [email protected]"\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; 
} 
+1

Вы забыли «новое». 'new ManagementObjectSearcher' ... – SepehrM

51

Чуть больше, чем было сделал запрос, но я использую дополнительный код таймера для отслеживания и оповещения, если загрузка процессора составляет 90% или выше в течение длительного периода 1 минуты или дольше.

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 = 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"; 
    } 
} 
+2

Где находится getRAMCounter()? –

1

Этот класс автоматически опрашивает счетчик каждые 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; 
    } 
} 
+0

'System.DateTime' - фактически 8-байтовый тип значения, что означает, что присвоения переменной' DateTime' не являются атомарными. Этот код не является потокобезопасным на 32-битных платформах. – andrewjs

18

Пробыв некоторое время на чтение через пару различные темы, которые казались довольно сложным, я придумал это. Мне это нужно для 8-ядерной машины, где я хотел бы контролировать SQL-сервер. В приведенном ниже коде я перешел в «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); 
     } 
    } 

Кажется, что правильно измеряет% процессора, используемого SQL на моем 8-ядерном сервере.

+0

total_cpu должен быть PerformanceCounter («Процессор»), а не PerformanceCounter («Процесс»). В противном случае вы просто получите 100% * количество ядер. –

2

Мне не понравилось, что нужно добавить в 1 секунду стойло ко всем решениям PerformanceCounter. Вместо этого я решил использовать решение WMI. Причина, по которой существует 1 секунда ожидания/стойки, заключается в том, чтобы обеспечить точность чтения при использовании PerformanceCounter. Однако, если вы часто вызываете этот метод и обновляете эту информацию, я бы посоветовал не постоянно брать на себя эту задержку ... даже если подумал о том, чтобы сделать асинхронный процесс, чтобы получить его.

Я начал с сниппета здесь Returning CPU usage in WMI using C# и добавил полное объяснение решения на моем блоге ниже:

Get CPU Usage Across All Cores In C# Using WMI

+1

Отличное решение и отличная запись в блоге! –

3

Это похоже на работу для меня, пример для ожидания до процессора достигает определенный процент

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

Почему вы спите, когда используется 0? – watashiSHUN