1

Ok so I'm trying to get the CPU usage using a PerformanceCounter in Visual Studio 2010 but the problem I'm having is when I add the PerformanceCounter and try to add a CategoryName the list is empty along with CounterName and InstanceName.

I also tried adding the counter using the following code but it still doesn't work:

Imports System.Diagnostics

Dim myCounter As System.Diagnostics.PerformanceCounter = New System.Diagnostics.PerformanceCounter()

myCounter.CategoryName = "Processor"
myCounter.CounterName = "% Processor Time"
myCounter.InstanceName = "_Total"

ProgressBar1.Value = myCounter.NextValue.ToString
cpuTxt.Text = "CPU Usage: " & ProgressBar1.Value.ToString & "%"

Any idea why this is happening? I've been searching for some time now and still can't get it to work. Any help is greatly appreciated.

Image: http://s11.postimg.org/y0vnpiwcz/screen.jpg

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Brian Moreno
  • 977
  • 4
  • 11
  • 39
  • 2
    The first call to NextValue *always* returns 0. The next call, wait at least a second, tells you how much cpu was used during that second. Do not recreate the object again or you'll get 0 again. – Hans Passant May 16 '15 at 17:26

2 Answers2

1

I assume you are actually polling the counter? Try something like this:

Option Strict On
Option Explicit On
Option Infer Off

Imports System.Diagnostics

Public Class Form1

    Private myCounter As System.Diagnostics.PerformanceCounter = New System.Diagnostics.PerformanceCounter()
    Private WithEvents poll As New Timer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myCounter.CategoryName = "Processor"
        myCounter.CounterName = "% Processor Time"
        myCounter.InstanceName = "_Total"
        poll.Interval = 1000
        poll.Enabled = True
    End Sub

    Private Sub poll_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles poll.Tick
        Dim val As Single = myCounter.NextValue
        ProgressBar1.Value = CInt(val)
        cpuTxt.Text = "CPU Usage: " & val.ToString & "%"
    End Sub

End Class

As Hans Passant and Plutonix have both pointed out in comments, you should only create the counter object once. Recreating the counter each time will only ever result in a reading of 0.

The Blue Dog
  • 2,475
  • 3
  • 19
  • 25
  • The OP does call `NextValue` but there is no context for the code posted. He might be creating a new one each time. (+1) – Ňɏssa Pøngjǣrdenlarp May 16 '15 at 17:27
  • @Plutonix: My thoughts exactly. This line `ProgressBar1.Value = myCounter.NextValue.ToString` also gave me a headache. – The Blue Dog May 16 '15 at 17:30
  • Thanks, yeah i was using a timer, but i tried out your code and I get the following error: `Unable to load data counter name because an index was read ' ' Invalid Registry` on the line `Dim val As Single = myCounter.NextValue`. – Brian Moreno May 16 '15 at 17:47
  • 1
    @ExoSkeleton321: Have a look at [this question](http://stackoverflow.com/questions/17980178/cannot-load-counter-name-data-because-an-invalid-index-exception). – The Blue Dog May 16 '15 at 17:52
0

There are likely a couple of factors at play here, PerformanceCounters need to be created before they are used, this action requires administrator access to the machine or sufficient escalation.

You will notice in the example provided by the MSDN the creation of the counter happens conditionally if the counter does not currently exist.

https://msdn.microsoft.com/en-us/library/system.diagnostics.performancecounter%28v=vs.110%29.aspx

Gent
  • 2,675
  • 1
  • 24
  • 34