上下文:
我想运行一个测试,并在运行时收集CPU利用率。基本上,当我开始测试时,我也想开始收集CPU利用率的数据,在测试结束时,我也想停止收集CPU利用率的数据(以及之后的平均值)。
在Win7的在PowerShell中获取测试执行的平均CPU利用率
方法使用PowerShell 3:
在测试开始时我还说,启动一个后台作业的功能。后台作业执行脚本块,该脚本运行'while($ true)'循环,收集平均CPU使用率并将其保存到文件中。在测试结束时,我读取文件,对收集到的数据进行平均,并停止并删除作业。
问题:
对于目前的做法,该脚本块并不总是得到执行,并没有新的数据被收集。如果我多次运行测试,scriptblock会被执行(在其中一个运行中) - 我无法想到任何与此相关或相关的行为。如果我在测试中的任何地方使用断点,scriptblock也会被执行。
想不到另一种方法。
想要的答案:
1.为什么不执行脚本块?以及如何让它执行?
2.在测试过程中是否有另一种方法来收集资源数据?
请注意,代码已经通过各种尝试和失败运行,不再'漂亮'。
代码:
function Start-ResourceMonitor
{
param()
[email protected]()
$timestamp = Get-Date -Format o | foreach {$_ -replace ":", "."}
$compName=$env:COMPUTERNAME
$myFilePath = Join-Path -path $env:TEMP -childpath .\temp_$timestamp.txt
$scriptBlock = {
$avgSB = $args[0]
$timestampSB = $args[1]
while ($true) {
$avgSB += Get-WmiObject win32_processor -computername $args[2] | Measure-Object -property LoadPercentage -Average | Foreach {$_.Average}
$avgSB | Out-File -FilePath $args[3] -Force
start-sleep -Milliseconds 500
}
}
$res = start-job -RunAs32 -Name 'MyJob' -ScriptBlock $scriptBlock -ArgumentList @($avg,$timestamp,$compName,$myFilePath)
while (($res.State -ne 'Running') -or (-not (Test-Path $myFilePath))){
start-sleep -Milliseconds 500
}
}
[other test functions]
function Stop-ResourceMonitor
{
param()
Stop-Job -Name MyJob
$testFN = Get-ChildItem -Path $env:TEMP -Filter "temp*.txt" | sort LastWriteTime -Descending | select -First 1
$global:CPU_Average = get-content -path $testFN.FullName
$global:CPU_Average | Measure-Object -Average | select -ExpandProperty Average | Write-Host
Remove-Job -Name MyJob
}
我担心'Job'已被添加,但执行尚未开始(即'State'没有变成'Running')。当你创建一个'Job'时,你放弃处理'Scriptblock'的调度。由于您正在等待'Job'开始执行,您是不是可以这样做,因为'Start-ResourceMonitor'中的最后一行是在一个循环中休眠,直到'Job'的'State'变为'Running '? –
@ robert.westerlund我试过了你的建议,但得到了同样的结果。为了调试目的(仅限本地版本),我在停止它之前输出作业状态,在Stop-ResourceMonitor中 - 在我所有的运行状态中,状态一直在运行。 – Mircea
是的,但是'Job'可能在你停止之前开始运行,也就是在你完成实际测试之后。如果在执行实际测试之前输出工作状态,我猜测它不处于'运行'状态。再一次,我只是在猜测,因为我不确定你是如何确定“scriptblock并不总是被执行的”。 –