2012-03-18 3 views
3

バックグラウンドジョブ(start-jobで始まる)を実行し、x秒後にタイムアウトしたいとします。私は別々の仕事ごとに実行時間を記録するのは難しいです(私は400のジョブを実行しています)。バックグラウンドジョブの実行時間の管理。 x秒後に完了しなければタイムアウトします。

ジョブをタイムアウトさせる方法があり、completedでない場合はfailedに設定したいと思っていますが、timeoutパラメータはありません。

ジョブの個々の実行時間を追跡するにはどうすればよいでしょうか?

私は、各ジョブの開始時刻とジョブIDでハッシュテーブルを作成し、running状態をチェックして手動タイムアウトを行うことができたと思います。 アイデア

このトピックに関する実り多い議論と偉大なインスピレーションに感謝します。あなたがWait-Jobのタイムアウトオプションを指定することができます

+1

私はたぶん最後の段落で言及したHashTableソリューションのようなものを考え出しました。良いアイデアのようだ。 –

答えて

3

あなたはタイマーのハッシュテーブルを使用することができます。

$jobtimer = @{} 

foreach ($job in $jobs){ 
    start-job -name $job -ScriptBlock {scriptblock commands} 
    $jobtimer[$job] = new-object [diagnostics.stopwatch]::startnew() 
    } 

各ジョブの実行時間は$ jobtimer [$ job]になります。

+0

これは完璧です。私はしかし、変数に設定せずに値を直接参照することに問題があります。どのように 'get-job | foreach { echo $ jobtimer [$ _。名前]。経過時間.0秒。} ' は動作しませんが、 ' $ jobtimer [4] .elapsed.totalseconds'は機能しますか? – Sune

2

-TIMEOUT

は秒で、それぞれのバックグラウンドジョブの最大待機時間を決定します。 デフォルトの-1は、 の実行時間に関係なく、ジョブが完了するまで待機します。 Start-Jobコマンドではなく、Wait-Jobコマンドを送信するタイミングが始まります。

この時間を超えると、ジョブがまだ実行中であっても、待機が終了し、コマンドプロンプト が返されます。エラーメッセージは と表示されません。

ここではいくつかのサンプルコードです:

この部分はいくつかのテストジョブを行います

Remove-Job -Name * 
$jobs = @() 
1..10 | % { 
    $jobs += Start-Job -ScriptBlock { 
     Start-Sleep -Seconds (Get-Random -Minimum 5 -Maximum 20) 
    } 
} 

変数$timedOutJobsがタイムアウトしましたジョブが含まれています。その後、それらを再起動することができます。

$jobs | Wait-Job -Timeout 10 
$timedOutJobs = Get-Job | ? {$_.State -eq 'Running'} | Stop-Job -PassThru 
+0

これも私の最初の考えでしたが、Wait-Jobの1つの問題は、それがブロックされていることです。OPの400ジョブが完了またはタイムアウトしている間にスクリプトが完全にブロックされた場合、これは機能します。 Wait-Job Timeoutの使用には暗黙の前提があり、すべてのジョブがほぼ同じ時刻に開始されます。 –

+0

@KeithHill Suneは、このスクリプトを開発しています。以前の質問の1つは、仕事を抑制する方法を扱っていました。私は400が同時に走っているとは思わない。 –

+0

あなたは正しい@AndyArismendiです!私は仕事を絞っている。その時に20歳しか走っていない(私はそれが素晴らしいスイートスポットであることがわかった)。スクリプトの最後(またはスクリプトのどこか)で待機ジョブを実行すると、スクリプトはタイムアウトしたすべてのジョブを再実行します。これを自分のスロットル・レベルに制限する必要があります。私はforeachループのハッシュテーブルに対してテストをしなければならないと思います。とにかくおかげ:) :) – Sune

3

だけでジョブを実行しているのリストを歩くと、あなたのタイムアウトスペック例えば過ぎて実行したことをいずれかを停止します。

 
$timeout = [timespan]::FromMinutes(1) 
$now = Get-Date 
Get-Job | Where {$_.State -eq 'Running' -and 
       (($now - $_.PSBeginTime) -gt $timeout)} | Stop-Job 

はBTWショーなどの書式を設定、デフォルトよりもジョブオブジェクトに複数のプロパティがあります。

 
3 > $job | fl * 


State   : Running 
HasMoreData : True 
StatusMessage : 
Location  : localhost 
Command  : Start-sleep -sec 30 
JobStateInfo : Running 
Finished  : System.Threading.ManualResetEvent 
InstanceId : de370ea8-763b-4f3b-ba0e-d45f402c8bc4 
Id   : 3 
Name   : Job3 
ChildJobs  : {Job4} 
PSBeginTime : 3/18/2012 11:07:20 AM 
PSEndTime  : 
PSJobType  : BackgroundJob 
Output  : {} 
Error   : {} 
Progress  : {} 
Verbose  : {} 
Debug   : {} 
Warning  : {} 
+1

Psbegintimeは私が探しているものです!しかし、私はそれを見つけることができません。 V2またはV3を実行していますか? – Sune

+0

現在V3を実行しています。 V2にそのフィールドがない場合は、$ jobオブジェクト(またはid)をジョブの作成時に作成するタイムスタンプにマップするためのハッシュテーブルを作成します。 –

+0

私はWin8のベータ版(PSv3)を使っていますが、私はPs *のプロパティを持っていないようです:/ '(Start-Job -ScriptBlock {gp} | gm -MemberType Property Ps *)。Count'は' 0'です。 。 –

関連する問題