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.
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
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.