2015-06-03 7 views
10

Was ich versuche zu tun, ist eine Funktion, um den Pipeline-Feed zu stoppen, wenn ein Zeitlimit erreicht wurde. Ich habe eine Testfunktion wie folgt erstellt:Stoppen PowerShell-Pipeline, stellen Sie sicher, Ende heißt

function Test-PipelineStuff 
{ 
    [cmdletbinding()] 
    Param(
     [Parameter(ValueFromPipeLIne=$true)][int]$Foo, 
     [Parameter(ValueFromPipeLIne=$true)][int]$MaxMins 
    ) 

    begin { 
     "THE START" 
     $StartTime = Get-Date 
     $StopTime = (get-date).AddMinutes($MaxMins) 
     "Stop time is: $StopTime" 
    } 

    process 
    { 
     $currTime = Get-Date 
     if($currTime -lt $StopTime){ 
      "Processing $Foo"    
     } 
     else{ 
      continue; 
     } 
    } 

    end { "THE END" } 
} 

Dies wird sicherlich die Pipeline stoppen, aber es nie ruft mein „end {}“ Block, der in diesem Fall lebenswichtig ist. Weiß jemand, warum mein Block "end {}" nicht aufgerufen wird, wenn ich die Pipeline mit "Weiter" stoppe? Das Verhalten scheint identisch zu sein, wenn ich eine PipelineStoppedException werfe.

+1

Vermutlich springt 'continue' aus seiner beinhaltenden Schleife heraus, nur gibt es keine, so dass es sich von Ihrer gesamten Funktion entfernt. Das ist aber nicht gerade hilfreich. Ich bin mir nicht sicher, ob es einen richtigen Weg gibt, um das zu tun, was Sie hier versuchen wollen. –

+1

Wie ich es verstehe, werden Cmdlets wie Select-Object -First 1 die StopUpstreamCommandsException auslösen, um die Pipeline zu stoppen, was eine interne Ausnahme ist und nicht für meine eigene Verwendung sichtbar ist. :( –

+0

Vielleicht setzen Sie Ihre 'end {}' Verarbeitung in einen anderen Skriptblock, den Sie aus der 'else {}' Klausel in 'process {}' aufrufen können? –

Antwort

2

Nach about_Functions:

Nachdem die Funktion alle Objekte in der Pipeline empfängt, läuft die End Anweisungsliste einmal. Wenn keine Anfangs-, Prozess- oder Endschlüsselwörter verwendet werden, werden alle Anweisungen wie eine End-Anweisungsliste behandelt.

So müssen Sie nur den else Block weglassen. Dann werden alle Objekte in der Pipeline verarbeitet, aber aufgrund der Klausel if wird die eigentliche Verarbeitung nur durchgeführt, bis das Zeitlimit erreicht ist.

+1

Wenn ich muß warten, bis es alle Objekte in der Pipeline zu verarbeiten, es negiert so ziemlich den Vorteil zu versuchen, ihm zu sagen, zu einem bestimmten Zeitpunkt zu stoppen. Ich versuche, dieses Skript zu stoppen, wenn es das Zeitlimit erreicht, und vermeiden, alle Elemente außerhalb dieses Limits zu verarbeiten. Natürlich kann ich den Endblock ausführen, wenn ich alles verarbeite, aber das ist nicht mein Ziel. –

+0

Die Frage war, warum der Endblock nie aufgerufen wird. Die Antwort ist, dass es nur aufgerufen wird, wenn alle Elemente in der Pipeline verarbeitet werden. –

+1

Nein, die Frage war, wie ich die Pipeline anhalten und sicherstellen kann, dass das Ende aufgerufen wird. –

0

Wenn Sie break/continue verwenden oder eine Ausnahme auslösen, wird die Funktion unweigerlich vorzeitig beendet (und auch eine umschließende Schleife unterbrochen/fortgesetzt).

Sie können jedoch einbetten eine Bereinigungsfunktion im begin Block, implementiert, was ursprünglich Sie Ihren end Block setzen in und rufen Sie diese Funktion aus beide Ihre process blockieren - kurz vor continue-und der end Block:

function Test-PipelineStuff 
{ 
    [cmdletbinding()] 
    Param(
     [Parameter(ValueFromPipeLine=$true)][int]$Foo, 
     [Parameter(ValueFromPipeLine=$true)][int]$MaxMins 
    ) 

    begin { 
     "THE START" 
     $StartTime = Get-Date 
     $StopTime = (get-date).AddMinutes($MaxMins) 
     "Stop time is: $StopTime" 

     # Embedded cleanup function. 
     function clean-up { 
      "THE END" 
     } 

    } 

    process 
    { 
     $currTime = Get-Date 
     if($currTime -lt $StopTime){ 
      "Processing $Foo"    
     } 
     else { 
      # Call the cleanup function just before stopping the pipeline. 
      clean-up 
      continue; 
     } 
    } 

    end { 
     # Normal termination: call the cleanup function. 
     clean-up 
    } 
} 
Verwandte Themen