#powershell
#powershell
Вопрос:
Мой код не может достичь конечной строки вывода:
$downloadCommand = {
$Response = Invoke-WebRequest -Uri "$someurl" -OutFile "$somelocation"
0
}
$job = Start-Job $downloadCommand
$sleeptime=10
While(Get-Job -State "Running")
{
#Get-Job -State "Running"
Start-Sleep -Seconds $sleeptime
}
Get-Job | Wait-Job
$result = Receive-Job -Job $job # <=== gets stuck here
Write-Host "Can't reach here"
Есть идеи, что я здесь делаю не так? Я знаю, что загрузка работает нормально, и она, безусловно, выходит из цикла while.
Комментарии:
1. Не могли бы вы, пожалуйста, определить или уточнить
get's stuck here
? Выполняется ли скрипт непрерывно в этот момент или что происходит?2. Скрипт просто зависает и продолжает выполняться непрерывно, пока я его не убью.
3. Создается / записывается ли файл в
$somelocation
? Если нет, попробуйте изменитьInvoke-WebRequest
вызов наInvoke-WebRequest -Uri "$someurl" -OutFile "$somelocation" -UseBasicParsing
4. Да, файл успешно записывается / загружается в это местоположение. Это zip-файл размером 180 МБ. Когда я закомментирую строку, которая застряла, остальная часть моего скрипта продолжается, и я могу распаковать этот файл. Как бы то ни было, я запускаю сценарий powershell таким образом (вызывается из .bat-скрипта) .:
powershell -NoProfile -ExecutionPolicy Unrestricted -command C:foo.ps1
Ответ №1:
Как ни странно, я не могу заставить ваш пример зависать бесконечно. Может быть, вы загружаете какой-то огромный файл? Возможно, ваш сервер назначения обрабатывает неопределенно долго?
Я изменил ваш скрипт, чтобы получить больше информации.
Если вы проверяете состояние задания и ждете с помощью Start-Sleep
— в вашем скрипте нет необходимости в Wait-Job.
Правильный способ ожидания задания:
$downloadCommand = {
Invoke-WebRequest -Uri "$someurl" -OutFile "$somelocation";
}
$job = Start-Job $downloadCommand;
$sleepTime = 10;
while ((Get-Job | Where-Object Id -eq $job.Id).State -eq "Running")
{
Write-Host "Waiting next $sleepTime seconds for job $($job.Id) to finish...";
Start-Sleep -Seconds $sleepTime;
}
Receive-Job $job;
Кстати, начиная с Powershell 7.0, вы можете использовать Foreach-Object -Parallel ( https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7)
Комментарии:
1. Это zip-файл размером 180 МБ. Что касается ненужного задания ожидания, я согласен с вами. На самом деле у меня его там изначально не было, и я просто разместил его там для наглядности. Итак, я скопировал ваш код и завернул инструкции вывода в Receive-Job:
Write-Host "-- Download Stopped." Receive-Job $job; Write-Host "-- Download Completed."
Последний вывод, который я вижу, это «— Загрузка остановлена». и выполнение зависает здесь, пока я не завершу его. И спасибо за предложение, но, к сожалению, мой компьютер все еще зависает на версии 5.1.