我想在Windows Server 2008上运行一个.NET控制台应用程序,它每2秒监视一次CPU使用情况。
如果任何单个应用程序使用> 30%CPU,连续两次,应该记录。
我将每2秒执行一次“CheckCpu”...但我的问题是,如何确定每个进程的CPU使用率?而且,有效以便我不会陷入我们的服务器:)
Dim lStrProcessCurrent As List(Of String)
Dim lStrProcessPrevious As List(Of String)
Private Sub CheckCpu()
Dim pcc As New PerformanceCounterCategory("Process")
'Clear "Current" run
lStrProcessCurrent = New List(Of String)
For Each instance As String In pcc.GetInstanceNames
Using cnt As PerformanceCounter = New PerformanceCounter("Process", "ID Process", instance, True)
Dim processName As String = cnt.InstanceName
' ????? HOW TO DETERMINE CPU USAGE ????
Dim cpuUsage As Long = 31
If cpuUsage >= 30 Then
'Was over 30% in Previous check
If lStrProcessPrevious.Contains(processName) Then
LogCpuSpike(processName)
End If
lStrProcessCurrent.Add(processName)
End If
End Using
Next
'Update "Previous" run
lStrProcessPrevious = lStrProcessCurrent
End Sub
答案 0 :(得分:1)
您可以尝试类似下面的代码。实际上,每次调用CheckCpu()时检查每个进程的TotalProcessorTime,然后从上一次运行中减去该值并除以两次检查之间经过的总时间。
Sub Main()
Dim previousCheckTime As New DateTime
Dim previousProcessList As New List(Of ProcessInformation)
' Kick off an initial check
previousCheckTime = Now
previousProcessList = CheckCPU(previousProcessList, Nothing)
For i As Integer = 0 To 10
Threading.Thread.Sleep(1000)
previousProcessList = CheckCPU(previousProcessList, Now - previousCheckTime)
previousCheckTime = Now
For Each process As ProcessInformation In previousProcessList
Console.WriteLine(process.Id & " - " & Math.Round(process.CpuUsage, 2).ToString & "%")
Next
Console.WriteLine("-- Next check --")
Next
Console.ReadLine()
End Sub
Private Function CheckCPU(previousProcessList As List(Of ProcessInformation), timeSinceLastCheck As TimeSpan) As List(Of ProcessInformation)
Dim currentProcessList As New List(Of ProcessInformation)
For Each process As Process In Process.GetProcesses()
' Id = 0 is the system idle process so we don't check that
If process.Id <> 0 Then
' See if this process existed last time we checked
Dim cpuUsage As Double = -1
Dim previousProcess As ProcessInformation = previousProcessList.SingleOrDefault(Function(p) p.Id = process.Id)
' If it did then we can calculate the % of CPU time it has consumed
If previousProcess IsNot Nothing AndAlso timeSinceLastCheck <> Nothing Then
cpuUsage = ((process.TotalProcessorTime - previousProcess.TotalProcessorTime).Ticks / (Environment.ProcessorCount * timeSinceLastCheck.Ticks)) * 100
End If
' Add to the current process list
currentProcessList.Add(New ProcessInformation With {.Id = process.Id, .CpuUsage = cpuUsage, .TotalProcessorTime = process.TotalProcessorTime})
End If
Next
Return currentProcessList
End Function
Class ProcessInformation
Public Id As Integer
Public TotalProcessorTime As TimeSpan
Public CpuUsage As Double
End Class
在生产环境中,您可能应该添加更多检查,因为在调用GetProcesses()然后处理列表之间可能会终止进程。如果该过程已经消失,那么当您尝试访问TotalProcessorTime属性时,您将收到错误。