Add a Pause or Delay

1. Problem

You want to pause or delay your script or command.

2. Solution

To pause until the user presses ENTER, use the Read-Host cmdlet:

        PS >Read-Host "Press ENTER"
        Press ENTER:

To pause until the user presses a key, use the ReadKey() method on the $host object:

        PS >$host.UI.RawUI.ReadKey()

To pause a script for a given amount of time, use the Start-Sleep cmdlet:

        PS >Start-Sleep 5
        PS >Start-Sleep -Milliseconds 300



3. Discussion

When you want to pause your script until the user presses a key or for a set amount of time, the Read-Host and Start-Sleep cmdlets are the two you are most likely to use. For more information about using the Read-Host cmdlet to read input from the user, see Section 12.1, “Read a Line of User Input.” In other situations, you may sometimes want to write a loop in your script that runs at a constant speed—such as once per minute, or 30 times per second. That is typically a difficult task, as the commands in the loop might take up a significant amount of time, or even an inconsistent amount of time.

In the past, many computer games suffered from solving this problem incorrectly. To control their game speed, game developers added commands to slow down their game. For example, after much tweaking and fiddling, the developers might realize that the game plays correctly on a typical machine if they make the computer count to one million every time it updates the screen. Unfortunately, these commands (such as counting)depend heavily on the speed of the computer. Since a fast computer can count to 1 million much more quickly than a slow computer, the game ends up running much quicker (often to the point of incomprehensibility)on faster computers!

To make your loop run at a regular speed, you can measure how long the commands in a loop take to complete, and then delay for whatever time is left, as shown in Example 4-1.

Example 4-1. Running a loop at a constant speed
$loopDelayMilliseconds = 650
while($true)
{
   $startTime = Get-Date
 
   ## Do commands here
   "Executing"
 
   $endTime = Get-Date
   $loopLength = ($endTime - $startTime).TotalMilliseconds
   $timeRemaining = $loopDelayMilliseconds - $loopLength
 
   if($timeRemaining -gt 0)
   {
      Start-Sleep -Milliseconds $timeRemaining
   }
}

Tags: , , , , , , , , , , ,