Как я могу поставить тайм-аут на команду powershell? - PullRequest
1 голос
/ 21 января 2020

Я попробовал этот код, но создается только file1.txt. File2.txt нет. Я ищу встроенный способ использования тайм-аутов. Так что не создавая пользовательские циклы.

Out-File "file1.txt"                  #this file is created

$Job = Start-Job -ScriptBlock {            
        Out-File "file2.txt"          #this file is not created
}
$Job | Wait-Job -Timeout 5
$Job | Stop-Job

Ответы [ 2 ]

1 голос
/ 21 января 2020

Я наконец нашел решение. Сценарий Start-Job запускается в домашней папке по умолчанию, отличной от местоположения сценария. Так что это работает, если я использую абсолютный путь. Мне нравится этот код гораздо лучше, чем пользовательские циклы:

Start-Job {                
    Out-File "C:\file2.txt"
} | Wait-Job -Timeout 3

0 голосов
/ 21 января 2020

Используя функцию Wait-Action, которая включает все эти функции в функцию PowerShell, загрузите ее из галереи PowerShell:

Install-Script -Name Wait-Action

Чтобы добавить Функция тайм-аута для сценария PowerShell требует нескольких различных задач:

Запуск таймера. Вызывайте какой-то фрагмент кода. Периодически проверяйте состояние кода. Если тайм-аут превышен, попросите PowerShell сделать что-то. Если тайм-аут не превышен, продолжайте с помощью скрипта Stop the timer

Первое, что нам нужно сделать, это определить время ожидания. Чаще всего срабатывает тайм-аут в секундах. Я хочу убедиться, что мой код не будет длиться более 10 секунд, поэтому я установлю для него переменную.

$Timeout = 10 ## seconds

Далее, мне нужно будет взять любой код, который я хочу ждать и добавьте его в блок скриптов. Для этого примера представьте, что я создал несколько фоновых заданий дальше по сценарию. Я хотел бы подождать, пока все эти задания не будут завершены, прежде чем продолжить.

$jobs = Get-Job
 $Condition = {param($jobs) 'Running' -not in $jobs.State }
 $ConditionArgs = $jobs

Далее мне нужно определить, как долго между проверками мой сценарий должен выполнять задачу.

$RetryInterval = 5 ## seconds

Теперь я запускаю таймер.

## Start the timer
 $timer = [Diagnostics.Stopwatch]::StartNew()

Теперь, когда таймер запущен, я могу теперь вызвать тот фрагмент кода, который мне нужно сделать.

## Start checking the condition scriptblock. Do this as long as the action hasn't exceeded
 ## the timeout or the condition scriptblock returns something other than $false or $null.
 while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and (& $Condition $ConditionArgs)) {

     ## Wait a specific interval
     Start-Sleep -Seconds $RetryInterval

     ## Check the time
     $totalSecs = [math]::Round($timer.Elapsed.TotalSeconds,0)
     Write-Verbose -Message "Still waiting for action to complete after [$totalSecs] seconds..."
 }

Один раз превышено время ожидания или задание выполнено, мне нужно будет остановить таймер.

## The action either completed or timed out. Stop the timer.
 $timer.Stop()

Теперь я могу проверить, превышено ли время ожидания или выполнено ли задание самостоятельно. , Здесь я добавляю исключение, указывающее, что действие не завершилось, если его остановил тайм-аут. В противном случае, я просто пишу подробное утверждение, что любой код может следовать после этого.

## Return status of what happened
 if ($timer.Elapsed.TotalSeconds -gt $Timeout) {
     throw 'Action did not complete before timeout period.'
 } else {
     Write-Verbose -Message 'Action completed before the timeout period.'
 }
...