在开始睡眠(或直到脚本结束)之后对象输出的奇怪延迟

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在开始睡眠(或直到脚本结束)之后对象输出的奇怪延迟相关的知识,希望对你有一定的参考价值。

由于某种原因,在完成睡眠命令之前,对象不会输出。

[pscustomobject]@message = 'hi'; sleep 5

这里是另一个例子。循环完成之前,您将看不到输出。

foreach ($i in 1..60)  
  if ($i -eq 1)  [pscustomobject]@message = $i  
  sleep 1

我想您必须至少输出2个对象才能看到任何东西? ¯\ _(ツ)_ /¯15秒后,您将看到两个对象。

foreach ($i in 1..60) 
  if ($i -eq 1 -or $i -eq 15)  [pscustomobject]@message = $i 
  sleep 1

或输出足够的属性(> 4)以隐式调用format-list而不是format-table。 格式表是问题。立即出现。

[pscustomobject]@a=1; b=2; c=3; d=4; e=5; sleep 10

我想知道是否可以像-NoWait一样添加格式表的参数。

具有包含列宽的格式文件的已知对象类型没有此问题。

foreach ($i in 1..60)  
  if ($i -eq 1)  get-process powershell  
  sleep 1

或默认为格式自定义的对象:

foreach ($i in 1..60)  
  if ($i -eq 1)  get-date  
  sleep 1

答案

此行为由臭名昭著的PSv5+ asynchronous behavior of implicitly applied Format-Table output解释:它最多等待300毫秒。在显示输出之前,努力确定合适的列宽。

如果您在该时间段之前使用Format-Table,则suspend等待睡眠的时间。

发生not触发隐式Start-Sleep格式的输出对象不受影响,但是:

Format-Table

相反,由于命令的输出是仅具有1属性的对象,并且其类型(# Immediate output, before sleeping ends: # Out-of-band formatting of a .NET primitive. PS> 1; Start-Sleep 5 # Implicit Format-*List* formatting due to having 5+ properties. PS> [pscustomobject]@a=1; b=2; c=3; d=4; e=5; sleep 10 )没有与之关联的预定义格式数据,因此它会触发隐式[pscustomobject]格式,因此会出现问题。

但是,请注意,这是一个display问题,并且如果命令被捕获或发送到管道,数据is会立即输出(尽管直到[C0 ]期已过去):

Format-Table

虽然有几种方法可以force同步(立即)显示输出,它们都改变了命令的基本行为

Start-Sleep
另一答案

将您的自定义对象放置到# The ForEach-Object command's script block receives the [pscustomobject] # instance right away (and itself prints it *immediately* to the display, # due to outputting a *string* (which never triggers the asynchronous behavior). & [pscustomobject]@message = 'hi'; sleep 5 | ForEach-Object "[$_]" cmdlet:

# Piping to Out-Host:
# Directly prints to the *display* (host).
# No way for a caller to capture the result or for processing
# the result in a pipeline.
[pscustomobject]@message = 'hi' | Out-Host; sleep 5

# Using Write-Host:
# Prints directly to the *display* (host) by default.
# While it *is* possible to capture the result via output stream 6.
# the information stream (6> file.txt), that output:
#  * is invariably converted to *strings*
#  * and the string representation does *not* use the friendly default
#    output formatting; instead, the objects are stringified with simple
#    [psobject.].ToString() calls, which results in a much less friendly
#    representation.
Write-Host ([pscustomobject]@message = 'hi'); sleep 5

# Piping to a Format-* cmdlet explicitly:
# While this does write to the success-output stream (stream number 1),
# as the command would by default, what is written isn't the original
# objects, but *formatting instructions*, which are useless for further
# programmatic processing.
# However, for redirecting the output to a file with Out-File or >
# this makes no difference, because they convert the formatting instructions
# to the strings you would see on the screen by default.
# By contrast, using Set-Content or any other cmdlet that expects actual data
# would not work meaningfully.
[pscustomobject]@message = 'hi' | Format-Table; sleep 5

[当使用Out-Host cmdlet时,您将立即向主机显示结果。没有它,对象将输出到管道,直到[pscustomobject]@message = 'hi' | Out-Host; sleep 5 cmdlet之后才返回。

以上是关于在开始睡眠(或直到脚本结束)之后对象输出的奇怪延迟的主要内容,如果未能解决你的问题,请参考以下文章

javascript中的延迟/睡眠?

3-22函数进阶——迭代器

Azure APIM 睡眠或延迟策略

Python迭代器(Iterator)

为啥 PyGame 在延迟或睡眠之前没有在窗口中绘制?

shell里面有没有比sleep短的