Delay-Wait-Sleep tricks.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Delay-Wait-Sleep tricks.

#31 Post by Squashman » 02 Nov 2013 18:29

Magialisk wrote:I'm starting to believe aGerman and jeb, the developers were on some good stuff...

New Mexico desert and too much Peyote.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Delay-Wait-Sleep tricks.

#32 Post by aGerman » 02 Nov 2013 18:54

I had to ask Google what Peyote means. It appears that I found that cactus on my window sill :shock: So don't trust my codes in future :lol:

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Delay-Wait-Sleep tricks.

#33 Post by penpen » 02 Nov 2013 19:24

Magialisk wrote:
penpen wrote:I then have used "ping -n 1 -w 800 1.1.1.1" on A.
I'm sure here you meant to say 192.168.0.11, but BRAVO!
Thanks :D .
But no, i've used 1.1.1.1, as 192.168.0.11 was existing and the running protocols on pc B may answer the ping request automatically.
If that happens it should be much faster than the 800ms, and the ping stops waiting and returns immediately.
The ping program only waits for 800 ms if it does not receive the ping reply.

penpen

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Delay-Wait-Sleep tricks.

#34 Post by Aacini » 03 Nov 2013 19:48

I think I achieved a milliseconds delay with precise timing when the delay is small. I used an hybrid Batch-JScript solution with WScript.Sleep method, but in order to avoid the load delay of the JScript section each time it is used, both parts must be active at same time. The JScript process take the delay in milliseconds, do the delay and send a signal to the Batch section. The Batch process send the number of milliseconds to JScript and wait for the signal. The way to achieve this bi-directional communication is via JScript's WshShwll.Exec method that have access to Batch process' Stdin and Stdout streams.

Code: Select all

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion
if "%~1" equ "restart" goto secondPart

rem First part: execute JScript section, so it re-execute this Batch file with "restart" parameter
CScript //nologo //E:JScript "%~F0" "%~F0 restart"
goto :EOF

:secondPart

rem To do a delay, use: "echo #millisecs" followed by "set /P ="; use "echo 0" to end
rem To display data in the screen, use:  echo data > CON
rem To read data from keyboard, use set /P "data=Prompt: " < CON > CON

set runs=10
For %%t in (5 10 15 20 30 50 100 250 500 1000) do (

   set time_idle_ms=%%t
   (
   set t0=!time!
   for /L %%p in (1,1,%runs%) do echo %%t& set /P =
   set t1=!time!
   )

   for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

   set /a average_time=a*10/runs
   echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms > CON
)

rem Send the signal to end JScript section
echo 0
goto :EOF


@end


// JScript section

// Restart this Batch file with access to its Stdin and Stdout streams
var WshShell = new ActiveXObject("WScript.Shell");
var BatchFile = WshShell.Exec(WScript.Arguments.Unnamed.Item(0)), delay;

// Get delay, wait and send CR until delay equ 0
while ((delay = BatchFile.Stdout.ReadLine()) != "0" ) {
   WScript.Sleep(delay);
   BatchFile.Stdin.WriteLine();
}


Output:

Code: Select all

Input:5 ms - Output: Average time 15 ms
Input:10 ms - Output: Average time 16 ms
Input:15 ms - Output: Average time 15 ms
Input:20 ms - Output: Average time 32 ms
Input:30 ms - Output: Average time 31 ms
Input:50 ms - Output: Average time 63 ms
Input:100 ms - Output: Average time 109 ms
Input:250 ms - Output: Average time 263 ms
Input:500 ms - Output: Average time 513 ms
Input:1000 ms - Output: Average time 1014 ms


Antonio

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Delay-Wait-Sleep tricks.

#35 Post by foxidrive » 03 Nov 2013 22:28

Nice work - Here is what I get in Windows 8.1 32 bit - 3.2 GHz

Code: Select all

Input:5 ms - Output: Average time 14 ms
Input:10 ms - Output: Average time 16 ms
Input:15 ms - Output: Average time 15 ms
Input:20 ms - Output: Average time 31 ms
Input:30 ms - Output: Average time 32 ms
Input:50 ms - Output: Average time 61 ms
Input:100 ms - Output: Average time 110 ms
Input:250 ms - Output: Average time 250 ms
Input:500 ms - Output: Average time 501 ms
Input:1000 ms - Output: Average time 1000 ms

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Delay-Wait-Sleep tricks.

#36 Post by einstein1969 » 04 Nov 2013 08:44

Aacini wrote:I think I achieved a milliseconds delay with precise timing when the delay is small. I used an hybrid Batch-JScript solution with WScript.Sleep method, but in order to avoid the load delay of the JScript section each time it is used, both parts must be active at same time. The JScript process take the delay in milliseconds, do the delay and send a signal to the Batch section. The Batch process send the number of milliseconds to JScript and wait for the signal. The way to achieve this bi-directional communication is via JScript's WshShwll.Exec method that have access to Batch process' Stdin and Stdout streams.

Code: Select all

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion
if "%~1" equ "restart" goto secondPart

rem First part: execute JScript section, so it re-execute this Batch file with "restart" parameter
CScript //nologo //E:JScript "%~F0" "%~F0 restart"
goto :EOF

:secondPart

rem To do a delay, use: "echo #millisecs" followed by "set /P ="; use "echo 0" to end
rem To display data in the screen, use:  echo data > CON
rem To read data from keyboard, use set /P "data=Prompt: " < CON > CON

set runs=10
For %%t in (5 10 15 20 30 50 100 250 500 1000) do (

   set time_idle_ms=%%t
   (
   set t0=!time!
   for /L %%p in (1,1,%runs%) do echo %%t& set /P =
   set t1=!time!
   )

   for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

   set /a average_time=a*10/runs
   echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms > CON
)

rem Send the signal to end JScript section
echo 0
goto :EOF


@end


// JScript section

// Restart this Batch file with access to its Stdin and Stdout streams
var WshShell = new ActiveXObject("WScript.Shell");
var BatchFile = WshShell.Exec(WScript.Arguments.Unnamed.Item(0)), delay;

// Get delay, wait and send CR until delay equ 0
while ((delay = BatchFile.Stdout.ReadLine()) != "0" ) {
   WScript.Sleep(delay);
   BatchFile.Stdin.WriteLine();
}


Output:

Code: Select all

Input:5 ms - Output: Average time 15 ms
Input:10 ms - Output: Average time 16 ms
Input:15 ms - Output: Average time 15 ms
Input:20 ms - Output: Average time 32 ms
Input:30 ms - Output: Average time 31 ms
Input:50 ms - Output: Average time 63 ms
Input:100 ms - Output: Average time 109 ms
Input:250 ms - Output: Average time 263 ms
Input:500 ms - Output: Average time 513 ms
Input:1000 ms - Output: Average time 1014 ms


Antonio


Great job! This is wonderfull! 8)

I will try as soon as possible because I am very interested in this method.

I was falling back on the "ping" my gateway (to Achieve fast response) or classical vbs script, but this seems even more promising.

Really thanks Aacini! :)


with respect,
Einstein1969
Last edited by einstein1969 on 27 Nov 2013 14:50, edited 1 time in total.

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Delay-Wait-Sleep tricks.

#37 Post by Ed Dyreen » 16 Nov 2013 22:46

aGerman wrote:
At least we gave the same advice :)

Indeed :lol:
Just one thing I'd like to mention:
1.1.1.1 could be a valid IP address. I would rather use an IP address that belongs to a reserved block.
See http://www.rfc-editor.org/rfc/rfc5737.txt

Code: Select all

>nul ping -n 1 -w 5000 192.0.2.0


Regards
aGerman
Hi aGerman,

why not just ping 0.0.0.0 ? This is an illegal IP not ?

I never had a ping response :roll:

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Delay-Wait-Sleep tricks.

#38 Post by aGerman » 17 Nov 2013 04:58

It is a valid IP address and it will be resolved to the local host name.
Try
ping -a 0.0.0.0
or
netstat -a

0.0.0.0 represents all IP addresses on the local machine. That's the reason why ping fails.

Regards
aGerman

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Delay-Wait-Sleep tricks.

#39 Post by penpen » 17 Nov 2013 06:29

There are some cases in which addresses like 0.0.0.0 are producing pings:
some are implementation errors of drivers (http://serverfault.com/questions/415784/why-and-or-how-is-something-to-replying-to-pings-as-0-0-0-0),
some are side effects from aliasing all unknown addresses to a predefined one,
and some (hardware) network monitors may respond to such an icmp ping request.

So you cannot be sure that a ping request will fail on a specific address.

The best solution is to define an ip adress in your network (class) (for example class C network: 192.0.0.0 to 223.255.255.255) that is forbidden to be used e.g. 192.168.0.254, and ping this (unused) ip address (NATs should be configured to filter out the pings).

penpen

Edit: But if the pc received a ping response, then it would not wait, too (same result as if ping fails: not waiting for the specified delay).

carlos
Expert
Posts: 503
Joined: 20 Aug 2010 13:57
Location: Chile
Contact:

Re: Delay-Wait-Sleep tricks.

#40 Post by carlos » 18 Nov 2013 12:01

I do some investigations and I found that the default values for ping in these options are the next (under xp):

Code: Select all

-l 32
-w 4000


Thn this is my code for do a delay in milliseconds:

replace "milliseconds" for the value

Code: Select all

ping -l 0 -n 1 -w milliseconds 1.0.0.0


Edited: I changed the ip for compatibility with Windows 8.
Last edited by carlos on 18 Nov 2013 13:53, edited 1 time in total.

carlos
Expert
Posts: 503
Joined: 20 Aug 2010 13:57
Location: Chile
Contact:

Re: Delay-Wait-Sleep tricks.

#41 Post by carlos » 18 Nov 2013 13:19

In Windows 8 0.0.0.0 is invalid. From 1.0.0.0 I can get the requested timeout for do the delay specified in -w option

in Windows 8:

C:\>ping -l 0 -n 1 -w 300 0.0.0.0

Pinging 0.0.0.0 with 0 bytes of data:
PING: transmit failed. General failure.

Ping statistics for 0.0.0.0:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -l 0 -n 1 -w 300 0.0.0.1

Pinging 0.0.0.1 with 0 bytes of data:
PING: transmit failed. General failure.

Ping statistics for 0.0.0.1:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -l 0 -n 1 -w 300 1.0.0.0

Pinging 1.0.0.0 with 0 bytes of data:
Request timed out.

Ping statistics for 1.0.0.0:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -l 0 -n 1 -w 300 1.1.1.1

Pinging 1.1.1.1 with 0 bytes of data:
Request timed out.

Ping statistics for 1.1.1.1:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
Last edited by carlos on 18 Nov 2013 13:54, edited 1 time in total.

carlos
Expert
Posts: 503
Joined: 20 Aug 2010 13:57
Location: Chile
Contact:

Re: Delay-Wait-Sleep tricks.

#42 Post by carlos » 18 Nov 2013 13:22

In Windows 8 and Windows XP: 0.0.0.0 produce General failure.
In Windows 8 0.0.0.1 produce General failure.
In Windows XP 0.0.0.1 produce Requested timeout.

There are a difference.

In windows 8 the valid ips for do a timeout are from: 1.0.0.0

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Delay-Wait-Sleep tricks.

#43 Post by einstein1969 » 27 Nov 2013 15:20

I post this function here, because often you use the time to calculate the elapsed time.

The variable %time% return a value in hundredths of a second but every little commits an error.

This function show the ERROR that there are in the get time of batch dos.

Show the number of GAP in the set returned.

Code: Select all

@echo off
rem detect where is the error!
setlocal EnableDelayedExpansion

echo Sync...to 00 or 01 %time%
:loopm100
if "%time:~-2%" neq "00" if "%time:~-2%" neq "01" goto :loopm100
echo %time%
echo(


set "st="
set ot=!time!
set obg=!ot!
set g2=0
:loop1100
(
  if "!time!" equ "!ot!" goto :loop1100
  set t=!time!
  set /a "d=1!t:~-2!-1!ot:~-2!, d+=(d>>31) & 100"
  if !d! gtr 1 if !d! equ 2 (set /a g2=g2+1) else (
   for /F "tokens=1-8 delims=:.," %%a in ("!obg: =0!:!ot: =0!") do set /a "db=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, db+=(db>>31) & 8640000, db+=d"
   echo Gap at !ot! + !d! = !t! [!g2! of 2] from !obg! [+!db!]
   set g2=0
   set obg=!t!
  )
  set ot=!t!
goto :loop1100
)


result:

Code: Select all

Gap at 22:13:43,64 + 3 = 22:13:43,67 [0 of 2] from 22:13:39,00 [+467]
Gap at 22:13:48,59 + 4 = 22:13:48,63 [1 of 2] from 22:13:43,67 [+496]
Gap at 22:13:53,19 + 10 = 22:13:53,29 [1 of 2] from 22:13:48,63 [+466]
Gap at 22:13:55,64 + 3 = 22:13:55,67 [0 of 2] from 22:13:53,29 [+238]
Gap at 22:14:02,45 + 3 = 22:14:02,48 [2 of 2] from 22:13:55,67 [+681]
Gap at 22:14:06,99 + 12 = 22:14:07,11 [0 of 2] from 22:14:02,48 [+463]
Gap at 22:14:12,64 + 4 = 22:14:12,68 [1 of 2] from 22:14:07,11 [+557]
Gap at 22:14:16,20 + 7 = 22:14:16,27 [1 of 2] from 22:14:12,68 [+359]
Gap at 22:14:16,27 + 3 = 22:14:16,30 [0 of 2] from 22:14:16,27 [+3]
Gap at 22:14:25,49 + 22 = 22:14:25,71 [2 of 2] from 22:14:16,30 [+941]
Gap at 22:14:30,24 + 14 = 22:14:30,38 [0 of 2] from 22:14:25,71 [+467]
Gap at 22:14:38,64 + 5 = 22:14:38,69 [2 of 2] from 22:14:30,38 [+831]
Gap at 22:14:41,64 + 6 = 22:14:41,70 [0 of 2] from 22:14:38,69 [+301]


There are gap where the time jump of 2. This function detect jump of 2 and >2

The jump of 2 are only counted. The jump >2 are show in each line.

Also measured the time since the last jump / gap >2

EDIT: why this analisys? because there are some schemes in the result! If you open an application the gaps increase. Even if you run in realtime!


Einstein1969

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Delay-Wait-Sleep tricks.

#44 Post by einstein1969 » 28 Nov 2013 10:33

Hi,
The best solution seems to be to use jscript or with some limitations with jscript in the pipe, but I still wanted to not let this opportunity with ping.

I had seen this method in the past and I reimplemented. It works with a router connected.
Use Ping to the router with big packet size to get a greater delay and therefore a lower CPU consumption.

It is not very accurate, but on my pc uses only 30-40% of cpu.
We can do better?

Code: Select all

@echo off & setlocal EnableDelayedExpansion

call :discovery_router router
echo Using %router% ...

For %%t in (5 50 100 200 250 500 1000 1500) do (

   set time_idle_ms=%%t
   set runs=100
   (
   set t0=!time!
   for /L %%p in (1,1,!runs!) do call :fake_ping !time_idle_ms! %router%
   set t1=!time!
   )

   for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

   set /a average_time=a*10/runs
   echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms
)

goto :eof

:discovery_router rem find router
  setlocal
  set "router="
  for /f "tokens=* delims=" %%f in ('tracert -d -h 1 -w 1 whatismyipaddress.com ^| find "ms"') do set "router=%%f"
  set "router=%router:~30%"
  if not defined router goto :discovery_router
  rem echo(router=!router!
  endlocal & set %1=%router%
goto :eof

:fake_ping %delay%ms %router%
setlocal
   set t0=%time%
:loop_fake_ping
   ping %~2 -n 1 -w 1 -l 32768 >nul
   for /F "tokens=1-8 delims=:.," %%a in ("%t0: =0%:%time: =0%") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000, a=a*10+20"
   if %a% lss %~1 goto :loop_fake_ping
   rem echo %t0% - %time% %a% [%1 %2]
endlocal
goto :eof


result: on windows 7 Mono processor

Code: Select all

Using   192.168.200.1  ...
Input:5 ms - Output: Average time 58 ms
Input:50 ms - Output: Average time 64 ms
Input:100 ms - Output: Average time 121 ms
Input:200 ms - Output: Average time 209 ms
Input:250 ms - Output: Average time 268 ms
Input:500 ms - Output: Average time 529 ms
Input:1000 ms - Output: Average time 1022 ms
Input:1500 ms - Output: Average time 1502 ms


EDIT : I have added a fix to compensate the error on %TIME%

Einstein1969

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Delay-Wait-Sleep tricks.

#45 Post by einstein1969 » 11 Jan 2014 15:53

Hi,

I have investigate on %time%.

The time is incremented every 15 or 16 millisecond.

Can anyone explain why?

This explain why there is a gap between centiseconds.

We can predict the error!

EDIT: the interval is near 15,65 ms

Einstein1969

Post Reply