2017-12-04 4 views
0

目標は、プロセスがウォッチファイルに書き込んでいる外部プロセスを監視するプログレスバーを持つことです。Mathが予期せず無限大「∞」を生成します

ループに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 2そして、それはECHO>wf.txt 1にある実行するために行うすべてたまにエラーがステップ2で発生し、時にはステップ3.

[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 
} 
+0

これは何を意味しますか? '$ currentcount = [int32](Get-Content $ WatchFile)'失敗した実行の 'Write-Verbose'の値は何ですか? – gms0ulman

+0

時計ファイルに2つまたは3つが含まれていても、$ currentcountはゼロ(0)として報告されます。それはなぜでしょうか? – lit

+0

今のところ、競争状態がそれを最もよく説明しています。特に、「スタート - スリープ」を助ける部分。この外部プロセスとは何ですか?あなたは解決策/回避策を見つけましたか? – gms0ulman

答えて

0

にあなたのコードは、単一のエンティティを処理しませんでしたが、あなたの$currentcountがありますあなたの素朴なETA計算は無限を返します。現在のカウントをゼロと比較することで、最初にETAを計算できるかどうかを確認する必要があります。

EDIT:あなたは文字列の配列を返すGet-Contentの暗黙的な変換を行っているので、あなたのファイルは、その中に改行を持っている場合は、変換エラーを取得し、あなたの$currentcountは、このようにあなたがゼロ除算、ゼロのままその無限を得る。 [IO.File]::ReadAllText()メソッドを使用するか、構文解析に最初の行(インデックス0)のみを使用する必要があります。または、-NoNewLineフラグをOut-Fileコマンドレットでファイルに書き込む必要があります。

+0

watchファイルから '$ currentcount'を取得しています。私はいつもそれを1(1)にしてから、1ずつ増やします。はい、これは後で確認するものです。それはなぜこれが機能していないのか説明しません。 – lit

+0

@litこの型キャストはエラーを返す可能性があり、 '$ currentcount'の値は変更されず、ゼロで初期化されます。ここで、顔をしてください。 – Vesper

+0

Start-Sleepがないとキャストに失敗するのはなぜですか?何かが失敗する可能性は常にあります。これは不規則なようです。 – lit

関連する問題