问题描述:

I am doing a form which displays performance data and i have a few performance counters that displays some information about the processor and memory. As the first results is always "0" i am doing a sleep thread before assigning the next value. The problem by doing this is that it really makes the program sluggish.

Even moving the window is slow, and i bet its due to the thread sleep event which basicly is running every other second. I have set the timers to always enabled with an interval of 1 second, cause i want it to display information "realtime" sort of.

Here is my code so far:

 private PerformanceCounter pcProcess; //Process

private PerformanceCounter pcMemory; //Memory

private void tmrProcess_Tick(System.Object sender, System.EventArgs e)

{

pcProcess = new PerformanceCounter(); //New Performance Counter Object

pcProcess.CategoryName = "Processor"; //Specify Process Counter

pcProcess.CounterName = "Interrupts/sec";

pcProcess.InstanceName = "_Total";

pcProcess.NextValue();

System.Threading.Thread.Sleep(1000);

cpInt.Text = pcProcess.NextValue().ToString(); //Display

pcProcess.CounterName = "% Processor Time";

pcProcess.InstanceName = "_Total";

pcProcess.NextValue();

System.Threading.Thread.Sleep(1000);

cpPower.Text = pcProcess.NextValue().ToString() + "%"; //Display

}

private void tmrMemory_Tick(System.Object sender, System.EventArgs e)

{

pcMemory = new PerformanceCounter();

pcMemory.CategoryName = "Memory";

//This counter gives a general idea of how many times information being requested is not where the application (and VMM) expects it to be

pcMemory.CounterName = "Available MBytes";

avlMem.Text = pcMemory.NextValue().ToString() + " Mb";

pcMemory.CounterName = "Page Faults/sec";

pcMemory.NextValue();

System.Threading.Thread.Sleep(1000);

pgFaults.Text = pcMemory.NextValue().ToString();

}

网友答案:
  • Drop the idea of calling Thread.Sleep. It's almost never a good idea.
  • Don't create a new instance of PerformanceCounter() on each timer tick, just call perfmonCounter.NextValue().
  • Call NextValue() once after the counter init so it'll returns something else than 0.0 on first timer tick. See remarks section on http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecounter.nextvalue(v=vs.110).aspx :

If the calculated value of a counter depends on two counter reads, the first read operation returns 0.0. Resetting the performance counter properties to specify a different counter is equivalent to creating a new performance counter, and the first read operation using the new properties returns 0.0. The recommended delay time between calls to the NextValue method is one second, to allow the counter to perform the next incremental read.

So basically:

private PerformanceCounter pcMemory;

private void InitPerfmon()
{
    this.pcMemory = new PerformanceCounter();
    this.pcMemory.CounterName = "Available MBytes";
    this.pcMemory.....
    ...
    this.pcMemory.NextValue();
}

private void tmrMemory_Tick(System.Object sender, System.EventArgs e)
{
    this.pgFaults.Text = this.pcMemory.NextValue().ToString();
}
相关阅读:
Top