2015-06-03 11 views
10

Điều tôi đang cố gắng thực hiện là có chức năng dừng nguồn cấp dữ liệu đường ống khi đạt đến giới hạn thời gian. Tôi đã tạo một chức năng thử nghiệm như sau:Dừng đường ống PowerShell, đảm bảo kết thúc được gọi là

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" } 
} 

Điều này chắc chắn sẽ dừng đường ống, nhưng nó không bao giờ gọi khối "cuối {}" của tôi, trong trường hợp này là rất quan trọng. Có ai biết tại sao khối "end {}" của tôi không được gọi khi tôi ngừng sử dụng đường dẫn "tiếp tục" không? Hành vi có vẻ giống nhau nếu tôi ném một PipelineStoppedException.

+1

Có lẽ 'tiếp tục' nhảy ra khỏi vòng chứa của nó chỉ có không có để nó nhảy rõ ràng về toàn bộ chức năng của bạn. Đó không phải là chính xác mặc dù hữu ích. Tôi không chắc chắn nếu có một cách thích hợp để làm những gì bạn đang cố gắng làm ở đây. –

+1

Như tôi đã hiểu, các lệnh ghép ngắn như Select-Object -First 1 sẽ tăng StopUpstreamCommandsException để dừng đường dẫn, ngoại lệ bên trong và không hiển thị cho mục đích sử dụng của riêng tôi. :( –

+0

Có thể đặt quá trình xử lý 'end {}' của bạn thành một đoạn mã lệnh khác mà bạn có thể gọi từ mệnh đề 'else {}' bên trong 'process {}'? –

Trả lời

2

Theo about_Functions:

Sau khi chức năng nhận được tất cả các đối tượng trong đường ống, kết thúc danh sách tuyên bố chạy một lúc. Nếu không có từ khóa Bắt đầu, Quy trình hoặc Kết thúc nào được sử dụng, tất cả các câu lệnh được xử lý như danh sách Sao kê kết thúc.

Vì vậy, bạn chỉ cần bỏ qua khối else. Sau đó, tất cả các đối tượng trong đường ống được xử lý, nhưng do điều khoản if xử lý thực tế chỉ được thực hiện cho đến khi giới hạn thời gian được nhấn.

+1

Nếu tôi phải đợi để xử lý tất cả các đối tượng trong đường ống, nó sẽ phủ nhận rất nhiều lợi ích của việc cố gắng yêu cầu dừng lại tại một thời điểm nhất định. Tôi đang cố gắng để có được kịch bản này để ngăn chặn nếu nó chạm thời hạn, và tránh xử lý tất cả các mục bên ngoài giới hạn đó. Tất nhiên tôi có thể nhận được khối kết thúc để thực thi nếu tôi xử lý mọi thứ, nhưng đó không phải là mục tiêu của tôi. –

+0

Câu hỏi đặt ra là tại sao khối kết thúc không bao giờ được gọi. Câu trả lời là, nó chỉ được gọi nếu tất cả các mục trong đường ống được xử lý. –

+1

Không, câu hỏi đặt ra là làm cách nào để tôi dừng kênh và đảm bảo kết thúc được gọi. –

0

Sử dụng break/continue hoặc ném ngoại lệ sẽ luôn thoát khỏi chức năng của bạn sớm (và cũng thoát ra khỏi/tiếp tục bất kỳ vòng lặp kèm theo).

Bạn có thể, tuy nhiên, nhúng một chức năng dọn dẹp trong khối begin mà thực hiện những gì bạn ban đầu được đưa vào end khối của bạn và gọi đó là chức năng từ cảprocess khối của bạn - ngay trước khi continue- các end khối:

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 
    } 
} 
Các vấn đề liên quan