2016-11-13 4 views
3

Получение:Получение InvalidOperationException при использовании PerformanceCounters

Exception брошенную: 'System.InvalidOperationException' в System.dll

Дополнительная информация:

Категория не существует.

Код:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace WindowsFormsApplication8 
{ 
public partial class Form1 : Form 
{ 
    PerformanceCounter cpuCounter; 
    PerformanceCounter ramCounter; 
    public Form1() 
    { 
     InitializeComponent(); 
    } 
    int timeX = 0; 
    private void timer1_Tick(object sender, EventArgs e) 
    { 
     cpuCounter = new PerformanceCounter(); 
     cpuCounter.CategoryName = "Processor"; 
     cpuCounter.CounterName = "% Processor Time"; 
     cpuCounter.InstanceName = "_Total"; 


     float cpuUsage = 0.00F; 
     cpuCounter.NextValue(); 
     cpuUsage = cpuCounter.NextValue(); 
     textBox1.Text = cpuUsage.ToString(); 


     ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 
     float ram = ramCounter.NextValue(); 
     textBox2.Text = ram.ToString(); 

     chart1.Series["CPU Usage"].Points.AddXY(timeX, (int)cpuUsage); 
     chart2.Series["Memory Use"].Points.AddXY(timeX, (int)ram); 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     timer1.Start(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     timer1.Stop(); 
    } 
} 
} 

Получение ошибки на каждом .nextValue();

Я попытался добавить Processor Information в CategoryName, но не помогает.

EDIT: @Jim это мой код после внесения изменений:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Diagnostics; 
namespace WindowsFormsApplication12 
{ 
public partial class Form1 : Form 
{ 
    PerformanceCounter cpuCounter; 
    PerformanceCounter ramCounter; 

    public Form1() 
    { 
     InitializeComponent(); 

     InitializeCounters(); 
    } 

    private void InitializeCounters() 
    { 
     cpuCounter = new PerformanceCounter(); 
     cpuCounter.CategoryName = "Processor"; 
     cpuCounter.CounterName = "% Processor Time"; 
     cpuCounter.InstanceName = "_Total"; 

     // ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 
    } 

    int timeX = 0; 
    private void timer1_Tick(object sender, EventArgs e) 
    { 
     float cpuUsage = 0.00F; 
     cpuUsage = cpuCounter.NextValue(); 
     textBox1.Text = cpuUsage.ToString(); 

     float ram = ramCounter.NextValue(); 
     textBox2.Text = ram.ToString(); 

     // Your chart stuff 
     //chart1.Series["CPU Usage"].Points.AddXY(timeX, (int)cpuUsage); 
     //chart2.Series["Memory Use"].Points.AddXY(timeX, (int)ram); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     timer1.Start(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     timer1.Stop(); 
    } 
} 

}

+1

Не могли бы вы по крайней мере дать нам трассировку стека и объяснить немного, что ты пытаясь сделать? – Fourat

ответ

2

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

Form1 Код За

PerformanceCounter cpuCounter; 
PerformanceCounter ramCounter; 

public Form1() 
{ 
    InitializeComponent(); 

    InitializeCounters(); 
} 

private void InitializeCounters() 
{ 
    cpuCounter = new PerformanceCounter(); 
    cpuCounter.CategoryName = "Processor"; 
    cpuCounter.CounterName = "% Processor Time"; 
    cpuCounter.InstanceName = "_Total"; 

    ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 
} 

int timeX = 0; 
private void timer1_Tick(object sender, EventArgs e) 
{   
    float cpuUsage = 0.00F; 
    cpuUsage = cpuCounter.NextValue(); 
    textBox1.Text = cpuUsage.ToString(); 

    float ram = ramCounter.NextValue(); 
    textBox2.Text = ram.ToString(); 

    // Your chart stuff 
    //chart1.Series["CPU Usage"].Points.AddXY(timeX, (int)cpuUsage); 
    //chart2.Series["Memory Use"].Points.AddXY(timeX, (int)ram); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    timer1.Start(); 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    timer1.Stop(); 
} 

примечание стороны:

Также Dispose счетчики, когда они не используются больше. Возможно, на мероприятии закрытие формы.

cpuCounter.Dispose(); 
ramCounter.Dispose(); 

Результат

enter image description here


Случай ошибки

Если мой пример еще выдает ошибку, это, скорее всего, потому что счетчики один или более высокую производительность на ваша система повреждена.

Перестроить все счетчики производительности:

  • Откройте командную строку (с правами администратора)
  • команда Run: lodctr /R

Сообщение:

Информация: Успешно перестроенная настройка счетчика производительности ...

появится при успешном завершении.

В случае, если вы получите сообщение:

Невозможно восстановить установку счетчика производительности из резервной системы магазина, код ошибки 2

Возможные решения:

  • Закрыть все работает программы
  • Убедитесь, что вы используете lodctr /R с прописными буквами R
  • Если в директории system32 переездом в каталог SysWOW64 (с CD ..> CD syswow64) и повторите команду lodctr /R в этом каталоге
+0

Я попробовал то, что вы сказали, и теперь я получаю исключение .NullReferenceException и «Ссылка на объект, не установленную на экземпляр объекта». – Commongrate

+0

@ Сопутствующий пример, который я сделал, будет исчерпан. Попробуйте создать новый проект winforms и добавьте код точно так же, как и мой, для тестирования. (Не пытайтесь вызвать 'InitializeCounters();' для инициализации счетчиков. Метод вызывается в моем примере в конструкторе формы. – Jim

+0

Я скопировал ваш код, добавил все и запустил его на ramCounter = new PerformanceCounter (" «Память», «Доступные MBytes»), строка i получила ту же ошибку «cat not exist», поэтому я прокомментировал ее и запустил, она запустилась, но когда я нажимаю кнопку 1, она не вызывает событие и текстовое поле пусто – Commongrate

0

Создание категории перед использованием PerformanceCounter. Более подробная информация и пример в msdn

const String categoryName = "Processor"; 
    const String counterName = "% Processor Time"; 

    if (!PerformanceCounterCategory.Exists(categoryName)) 
    { 

     CounterCreationDataCollection CCDC = new CounterCreationDataCollection(); 

     // Add the counter. 
     CounterCreationData ETimeData = new CounterCreationData(); 
     ETimeData.CounterType = PerformanceCounterType.ElapsedTime; 
     ETimeData.CounterName = counterName; 
     CCDC.Add(ETimeData);  

     // Create the category. 
     PerformanceCounterCategory.Create(categoryName, 
       "Demonstrates ElapsedTime performance counter usage.", 
      PerformanceCounterCategoryType.SingleInstance, CCDC); 
    } 
Смежные вопросы