Search code examples
powershellobjectoutputsleep

weird delay of the output of an object when followed by start-sleep (or until script end)


For some reason, the object won't output until the sleep command is done.

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

Here's another example. You won't see the output until the loop finishes.

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

I guess you have to output at least 2 objects to see anything? ¯\_(ツ)_/¯ After 15 seconds, you see both objects.

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

Or output enough properties (> 4) to implicitly call format-list instead of format-table. Format-table is the problem. This comes out right away.

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

I wonder if a parameter to format-table could be added like -NoWait.

Known object types with format files containing column widths don't have this problem.

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

Or objects that default to format-custom:

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

Solution

  • Output less than 5 properties, and format-table implicitly runs. Format-table will wait an indefinite amount of time for the second object, before displaying the first object. This is for object types (like pscustomobject) without an xml file that define a default table view.

    # no output for 5 seconds
    
    &{get-date
    sleep 5
    get-date} | format-table
    
    
    DisplayHint DateTime                               Date                 Day DayOfWeek DayOfYear Hour  Kind Millisecond Minute
    ----------- --------                               ----                 --- --------- --------- ----  ---- ----------- ------
       DateTime Saturday, February 8, 2020 10:24:48 AM 2/8/2020 12:00:00 AM   8  Saturday        39   10 Local         618     24
       DateTime Saturday, February 8, 2020 10:24:53 AM 2/8/2020 12:00:00 AM   8  Saturday        39   10 Local         892     24
    

    Compare with format-list:

    & {get-date
    sleep 5
    get-date} | format-list 
    
    DisplayHint : DateTime
    Date        : 2/8/2020 12:00:00 AM
    Day         : 8
    DayOfWeek   : Saturday
    DayOfYear   : 39
    Hour        : 20
    Kind        : Local
    Millisecond : 408
    Minute      : 37
    Month       : 2
    Second      : 18
    Ticks       : 637167910384087860
    TimeOfDay   : 20:37:18.4087860
    Year        : 2020
    DateTime    : Saturday, February 8, 2020 8:37:18 PM
    
    DisplayHint : DateTime
    Date        : 2/8/2020 12:00:00 AM
    Day         : 8
    DayOfWeek   : Saturday
    DayOfYear   : 39
    Hour        : 20
    Kind        : Local
    Millisecond : 662
    Minute      : 37
    Month       : 2
    Second      : 23
    Ticks       : 637167910436622480
    TimeOfDay   : 20:37:23.6622480
    Year        : 2020
    DateTime    : Saturday, February 8, 2020 8:37:23 PM