Question

I'm calculating the CPU usage on several of my servers. But the calculating is very, very slow.

Here is my code so far:

While it <= 5
    Dim myOptions As New ConnectionOptions
    myOptions.Username = _myParameters("user")
    myOptions.Password = _myParameters("password")

    Dim myRoot As String = "\\" & _myParameters("server") & "\root\cimv2"
    Dim myScope As New ManagementScope(myRoot, myOptions)

    Dim myQuery As New ObjectQuery(String.Format("select * from Win32_Processor"))

    Dim mySearcher As New ManagementObjectSearcher(myScope, myQuery)
    Dim myCollection As ManagementObjectCollection = mySearcher.Get

    For Each OS As ManagementObject In myCollection
        values.Add(OS("LoadPercentage"))
    Next

    Threading.Thread.Sleep(100) //Set some time between two calculations
    itCounter += 1
End While

The code hangs every time on

For Each OS As ManagementObject In myCollection

The application loses about 2-3 seconds there. In case of one CPU that is not a problem. But in our case

  • Calculate average using 5 reads

    2.5 sec * 5 = 12.5 secs

  • Monitoring some 15 CPU's

    12.5 sec * 15 = 3min

3 min between two updates is just too long.

Question: The reason and the solution of this delay?

Note: This code already runs in another thread.

Note2: Eventual C# code is welcome as well

Solution (With many,many thanks to Jon Egerton)

For future viewers, this solution solved it for me:

        Dim logon As New DlaLogon // control used for impersonation
        logon.impersonateValidUser(//Impersonate here using username + password)
        Dim cpuPerformance As New PerformanceCounter()
        cpuPerformance.MachineName = myParameters("server") //myServername
        cpuPerformance.CategoryName = "Processor"
        cpuPerformance.CounterName = "% Processor Time"
        cpuPerformance.InstanceName = "_Total"

        // Calculate average over 5 times
        While it <= 5
            //Add the result to List 'CpuReads'
            //We will calculate the average based on that list
            cpuReads.Add(cpuPerformance.NextValue())
            Threading.Thread.Sleep(500) // sleep for 0.5 sec 
            it += 1
        End While
        it = 0 
        logon.undoImpersonation() // Undo impersonation

I hope it may be of some use

Was it helpful?

Solution

The System.Diagnostics namespace contains the PerformanceCounter which can be used for obtaining information like this without actually impacting the system as it goes.

This answer Gives a nice example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top