数学意外产生无穷大“∞”

Math unexpectedly produces infinity '∞'

目标是让进度条监控外部进程,将其所在的步骤写入监视文件。

如果我在循环中没有Start-Sleep,它会产生无法转换无穷大的消息。为什么是这样?我愿意有一些睡眠时间,但为什么需要它,最少需要多少时间睡觉?

PS C:\src\t\pb> .\Monitor-Progress2.ps1 -TotalCount 5 -WatchFile wf.txt -Verbose
New-TimeSpan : Cannot bind parameter 'Seconds'. Cannot convert value "∞" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
At C:\src\t\pb\Monitor-Progress2.ps1:46 char:37
+ ... an -Seconds (($ts.TotalSeconds / $currentCount) * ($TotalCount - $cur ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [New-TimeSpan], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewTimeSpanCommand

这是代码。同样的问题出现在 PowerShell 5.1 和 6.0 上。我对运行所做的就是ECHO>wf.txt 1,然后是ECHO>wf.txt 2,等等。有时错误发生在第二步,但有时发生在第三步。

[CmdletBinding()]
Param (
    [Parameter(Mandatory=$true)]
    [int]$TotalCount

    ,[Parameter(Mandatory=$true)]
    [ValidateScript({Test-Path $_ -PathType 'Leaf'})]
    [string]$WatchFile
)

$currentcount = 0
$previouscount = $currentcount

$starttimestamp = Get-Date

while ($currentcount -lt $TotalCount) {
    $currentcount = [int32](Get-Content $WatchFile)

    ### Write-Verbose $currentcount

    if (($currentcount -lt $TotalCount) -and ($currentcount -ne $previouscount)) {
        $ts = $(Get-Date) - $starttimestamp

        ### Write-Verbose $ts.TotalSeconds
        ### Write-Verbose $currentcount
        ### Write-Verbose ($ts.TotalSeconds / $currentcount)
        ### Write-Verbose ($TotalCount - $currentcount)
        ### Write-Verbose (($ts.TotalSeconds / $currentcount) * ($TotalCount - $currentcount))

        $et = New-TimeSpan -Seconds (($ts.TotalSeconds / $currentCount) * ($TotalCount - $currentcount))
        $runningstatus = "Long process running for {0:%d} days {0:%h} hours {0:%m} minutes {0:%s} seconds" -f $ts
        $completionstatus = "Estimated completion in {0:%d} days {0:%h} hours {0:%m} minutes {0:%s} seconds" -f $et
        Write-Progress -Activity $runningstatus `
            -Status $completionstatus `
            -percentComplete ($currentcount / $TotalCount*100)
        $previouscount = $currentcount
    }

    #Start-Sleep -Seconds 1
}

虽然您的代码没有处理单个实体,但您的 $currentcount 为零,因此您的天真 ETA 计算 returns 无穷大。您应该先检查是否可以通过将当前计数与零进行比较来计算 ETA。

编辑:您已经对 Get-Content 进行了隐式转换,其中 returns 是一个 数组 字符串,因此如果您的文件中有一个换行符,你得到一个转换错误并且你的 $currentcount 保持为零,因此你除以零得到无穷大。您应该使用 [IO.File]::ReadAllText() 方法,或者仅使用第一行(索引为 0)进行解析。或者您应该将带有 -NoNewLine 标志的文件写入 Out-File cmdlet。