在 powershell 脚本中添加超时部分
Adding Time out section in powershell script
我正在尝试测试 30 秒后超时。
示例代码:
$a = "y"
$b = "n"
$timeout = New-TimeSpan -Seconds 30
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$stopwatch.Start()
$timeout.Seconds
$stopwatch.elapsed.Seconds
do{
if($a -eq "n"){
Write-Host "This block will never run"
break
}
if($stopwatch.elapsed.Seconds -lt $timeout.Seconds){
Write-Host "Testing this block: Time OUT!!"
break
}
}while($a -eq $b)
$stopwatch.Stop()
但是 if 块 if($stopwatch.elapsed.Seconds -lt $timeout.Seconds) 为真,即使 $stopwatch.elapsed.Seconds 值为 0 而 $timeout.Seconds 值为 30循环并在几毫秒内完成代码,而不是花费 30 秒来打印超时语句。
谁能给我指点以解决这个问题。
几件事:
- 您不需要这两行:循环上方的
$timeout.Seconds
和 $stopwatch.elapsed.Seconds
- 你的 while 条件应该是
while($a -ne $b)
- 循环内的测试应为
if($stopwatch.elapsed.Seconds -ge $timeout.Seconds)
尝试
$a = "y"
$b = "n"
$timeout = New-TimeSpan -Seconds 30
$stopwatch = [System.Diagnostics.Stopwatch]::new()
$stopwatch.Start()
do {
if($stopwatch.Elapsed.Seconds -ge $timeout.Seconds){
Write-Host "Testing this block: Time OUT!!"
break
}
# no timeout, so proceed with what needs to be done here
# . . .
} while($a -ne $b) # loop forever unless you set $a equal to $b in the loop somewhere
$stopwatch.Stop()
解决了您的方法中附带的 逻辑 问题,并提供了一个 可能 有效但无效的解决方案完全稳健:如果在测试超时条件之前循环 中的 activity 超过 1 分钟 ,测试将不会按预期进行(即使逻辑问题已修复)。
你有两个选择:
使用 .TotalSeconds
而不是 .Seconds
,原因如下所述。
更简单地说,利用 [timespan]
实例可直接比较的事实(见下文),您可以使用:
if ($stopwatch.elapsed -gt $timeout) { # ...
作为 zett42 points out, [timespan]
instances are directly comparable, due to implementing the .NET System.IComparable
界面(以及它的通用对应物);例如:
# -> $true - a timespan representing a 61-second duration
# is greater than one representing a 60-second (1-minute) duration.
[timespan]::FromSeconds(61) -gt [timespan] '00:01:00'
因此,如上一节所示,您可以直接比较 $stopwatch.elapsed
和 $timeout
- 两者都是 [timespan]
个实例。
[timespan]
实例的.Seconds
属性是只有秒分量,可能与 更大的 单位一起使用,例如分钟 (.Minutes
) 和小时 (.Hours
)
您需要 .TotalSeconds
属性 才能获得 总 秒数(类似地,还有 .TotalDays
、.TotalHours
和 .TotalMinutes
属性)。
另请注意 .Seconds
始终是 整数 ([int]
),而 .TotalSeconds
可以是 分数值 ([double]
).
为了说明区别:
PS> [timespan] '00:01:05' | # 1 minute and 5 seconds
Select-Object Seconds, TotalSeconds
Seconds TotalSeconds
------- ------------
5 65
@sivam 问题是-
- 如果超过 59 秒,则您没有应用 timespan 命令的正确属性,然后在 60 秒时将其视为 1 分钟。
- 更新循环内的条件 if($stopwatch.elapsed.Seconds -lt $timeout.Seconds)
尝试
$a = "y"
$b = "n"
$timeout = New-TimeSpan -Minutes 1
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$stopwatch.Start()
$timeout.Minutes
$stopwatch.elapsed.Minutes
do{
if($a -eq "n"){
Write-Host "This block will never run"
break
}
if($stopwatch.elapsed.Minutes -ge $timeout.Minutes){
Write-Host "Time OUT!!"
break
}
}while($a -ne $b)
$stopwatch.Stop()
我正在尝试测试 30 秒后超时。
示例代码:
$a = "y"
$b = "n"
$timeout = New-TimeSpan -Seconds 30
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$stopwatch.Start()
$timeout.Seconds
$stopwatch.elapsed.Seconds
do{
if($a -eq "n"){
Write-Host "This block will never run"
break
}
if($stopwatch.elapsed.Seconds -lt $timeout.Seconds){
Write-Host "Testing this block: Time OUT!!"
break
}
}while($a -eq $b)
$stopwatch.Stop()
但是 if 块 if($stopwatch.elapsed.Seconds -lt $timeout.Seconds) 为真,即使 $stopwatch.elapsed.Seconds 值为 0 而 $timeout.Seconds 值为 30循环并在几毫秒内完成代码,而不是花费 30 秒来打印超时语句。
谁能给我指点以解决这个问题。
几件事:
- 您不需要这两行:循环上方的
$timeout.Seconds
和$stopwatch.elapsed.Seconds
- 你的 while 条件应该是
while($a -ne $b)
- 循环内的测试应为
if($stopwatch.elapsed.Seconds -ge $timeout.Seconds)
尝试
$a = "y"
$b = "n"
$timeout = New-TimeSpan -Seconds 30
$stopwatch = [System.Diagnostics.Stopwatch]::new()
$stopwatch.Start()
do {
if($stopwatch.Elapsed.Seconds -ge $timeout.Seconds){
Write-Host "Testing this block: Time OUT!!"
break
}
# no timeout, so proceed with what needs to be done here
# . . .
} while($a -ne $b) # loop forever unless you set $a equal to $b in the loop somewhere
$stopwatch.Stop()
你有两个选择:
使用
.TotalSeconds
而不是.Seconds
,原因如下所述。更简单地说,利用
[timespan]
实例可直接比较的事实(见下文),您可以使用:if ($stopwatch.elapsed -gt $timeout) { # ...
作为 zett42 points out, [timespan]
instances are directly comparable, due to implementing the .NET System.IComparable
界面(以及它的通用对应物);例如:
# -> $true - a timespan representing a 61-second duration
# is greater than one representing a 60-second (1-minute) duration.
[timespan]::FromSeconds(61) -gt [timespan] '00:01:00'
因此,如上一节所示,您可以直接比较 $stopwatch.elapsed
和 $timeout
- 两者都是 [timespan]
个实例。
[timespan]
实例的.Seconds
属性是只有秒分量,可能与 更大的 单位一起使用,例如分钟 (.Minutes
) 和小时 (.Hours
)
您需要 .TotalSeconds
属性 才能获得 总 秒数(类似地,还有 .TotalDays
、.TotalHours
和 .TotalMinutes
属性)。
另请注意 .Seconds
始终是 整数 ([int]
),而 .TotalSeconds
可以是 分数值 ([double]
).
为了说明区别:
PS> [timespan] '00:01:05' | # 1 minute and 5 seconds
Select-Object Seconds, TotalSeconds
Seconds TotalSeconds
------- ------------
5 65
@sivam 问题是-
- 如果超过 59 秒,则您没有应用 timespan 命令的正确属性,然后在 60 秒时将其视为 1 分钟。
- 更新循环内的条件 if($stopwatch.elapsed.Seconds -lt $timeout.Seconds)
尝试
$a = "y"
$b = "n"
$timeout = New-TimeSpan -Minutes 1
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$stopwatch.Start()
$timeout.Minutes
$stopwatch.elapsed.Minutes
do{
if($a -eq "n"){
Write-Host "This block will never run"
break
}
if($stopwatch.elapsed.Minutes -ge $timeout.Minutes){
Write-Host "Time OUT!!"
break
}
}while($a -ne $b)
$stopwatch.Stop()