使用 PerformanceCounters 时出现 InvalidOperationException
Getting InvalidOperationException when using PerformanceCounters
获得:
Exception thrown: 'System.InvalidOperationException' in System.dll
附加信息:
Category does not exist.
代码:
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();
上出现错误
我试过在 CategoryName
中添加 Processor Information
,但也无济于事。
编辑:
@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();
}
}
}
在使用 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);
}
每次计时器滴答时您都在创建新的性能计数器,您只需要初始化 计数器一次。
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();
结果
错误案例
如果我的示例仍然出现错误,这很可能是因为您系统上的一个或多个性能计数器已损坏。
重建所有性能计数器:
- 打开命令提示符(具有管理员权限)
- 运行 命令:
lodctr /R
留言:
Info: Successfully rebuilt performance counter setting ...
成功后会出现
如果您收到消息:
Unable to rebuild performance counter setting from system backup store, error code is 2
可能的解决方案:
- 关闭所有 运行 程序
- 确保使用大写
lodctr /R
R
- 如果在目录 system32 中移动到目录 SysWOW64(使用 cd.. > cd syswow64)并在此目录中重试
lodctr /R
命令
获得:
Exception thrown: 'System.InvalidOperationException' in System.dll
附加信息:
Category does not exist.
代码:
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();
我试过在 CategoryName
中添加 Processor Information
,但也无济于事。
编辑: @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();
}
}
}
在使用 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);
}
每次计时器滴答时您都在创建新的性能计数器,您只需要初始化 计数器一次。
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();
结果
错误案例
如果我的示例仍然出现错误,这很可能是因为您系统上的一个或多个性能计数器已损坏。
重建所有性能计数器:
- 打开命令提示符(具有管理员权限)
- 运行 命令:
lodctr /R
留言:
Info: Successfully rebuilt performance counter setting ...
成功后会出现
如果您收到消息:
Unable to rebuild performance counter setting from system backup store, error code is 2
可能的解决方案:
- 关闭所有 运行 程序
- 确保使用大写
lodctr /R
R
- 如果在目录 system32 中移动到目录 SysWOW64(使用 cd.. > cd syswow64)并在此目录中重试
lodctr /R
命令