2013-08-09 2 views
1

Код работает в интерактивном режиме, в PS1-файле это не так. воспроизвести, открыть PowerShell, вставить функцию, а затем запустить get-job, чтобы увидеть задачу. тип get-job | remove-job после его завершения, а затем поместить код в файл PS1, он запускает только первые два, а затем выходит.Скрипт Powershell работает в интерактивном режиме, а не внутри сценария

function RunJobFromQueue 
{ 

    if($queue.Count -gt 0) 

    { 
     $cn = $queue.Dequeue() 

     $j = Start-Job -name $cn -ScriptBlock {param($x); Start-Sleep -Seconds 10;"output - " + $x} -ArgumentList $cn 

     Register-ObjectEvent -InputObject $j -EventName StateChanged -Action {RunJobFromQueue; Unregister-Event $eventsubscriber.SourceIdentifier; Remove-Job $eventsubscriber.SourceIdentifier } | Out-Null 
    } 

} 

$maxConcurrentJobs = 2 
$jobInput = "test1", "test2", "test3", "test4", "test5", "test6" 
$queue = [System.Collections.Queue]::Synchronized((New-Object System.Collections.Queue)) 
foreach($item in $jobInput) {$queue.Enqueue($item)} 

for($i = 0; $i -lt $maxConcurrentJobs; $i++){RunJobFromQueue} 

ответ

4

На моем взгляде: он не в сценарии, потому что:

  • запуска сценарий, определить функции и переменные в области скрипта
  • сценарий завершается, как только он определяет 2 начальных задания
  • работы полных , зарегистрированное действие запускается, но ваша функция не видна ему (определяется в области сценария), поэтому она терпит неудачу.

два варианта решить/работу вокруг него:

  • определяют функцию RunJobFromQueue в глобальном масштабе (function Global:RunJobFromQueue, $global:queue)
  • точка-источник скрипт (. .\YourScript.ps1)

Это работает в интерактивном режиме, потому что в этом случае вы определяете функцию/переменную в глобальной области видимости, поэтому -Action может найти их просто отлично.

+0

Спасибо, я дам ему шанс и спасибо за объяснение, почему .. –

Смежные вопросы