Jump to content

InetClose() hang program for several seconds...


Tersion
 Share

Recommended Posts

Here test example:

Spoiler
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <InetConstants.au3>
#include <GuiListView.au3>

#Region ### START Koda GUI section ### Form=
$hMainForm = GUICreate("Testing simultaneous downloads...", 296, 266, 192, 124)
$idListView = GUICtrlCreateListView("Downloads", 5, 5, 205, 255)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 200)
$idDownload_Button = GUICtrlCreateButton("Download", 215, 5, 75, 25)
$idCancel_Button = GUICtrlCreateButton("Cancel", 215, 35, 75, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Local $hDownload_1, $hDownload_2, $hDownload_3
Local $aSelectedIndex
Local $iDownloadCount = 3

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $idDownload_Button
            _GUICtrlListView_DeleteAllItems($idListView)
            If $hDownload_1 <> "" Then
                InetClose($hDownload_1)
                $hDownload_1 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & "\1-BigBuckBunny_320x180.mp4", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
            Else
                $hDownload_1 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & "\1-BigBuckBunny_320x180.mp4", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
            EndIf
            If $hDownload_2 <> "" Then
                InetClose($hDownload_2)
                $hDownload_2 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & "\2-BigBuckBunny_320x180.mp4", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
            Else
                $hDownload_2 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & "\2-BigBuckBunny_320x180.mp4", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
            EndIf
            If $iDownloadCount == 3 Then
                If $hDownload_3 <> "" Then
                    InetClose($hDownload_3)
                    $hDownload_3 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & "\3-BigBuckBunny_320x180.mp4", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
                Else
                    $hDownload_3 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & "\3-BigBuckBunny_320x180.mp4", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
                EndIf
            EndIf
            _GUICtrlListView_AddItem($idListView, "Download 1 is started!")
            _GUICtrlListView_AddItem($idListView, "Download 2 is started!")
            If $iDownloadCount == 3 Then
                _GUICtrlListView_AddItem($idListView, "Download 3 is started!")
            Else
                _GUICtrlListView_AddItem($idListView, "Only two simultaneous downloads!")
            EndIf
            AdlibRegister("UpdateDownloadInfo", 1000)
        Case $idCancel_Button
            $aSelectedIndex = _GUICtrlListView_GetSelectedIndices($idListView, True)
            Switch $aSelectedIndex[1]
                Case 0
                    InetClose($hDownload_1)
                    _GUICtrlListView_SetItemText($idListView, 0, "Download 1 is canceled!")
                Case 1
                    InetClose($hDownload_2)
                    _GUICtrlListView_SetItemText($idListView, 1, "Download 2 is canceled!")
                Case 2
                    InetClose($hDownload_3)
                    _GUICtrlListView_SetItemText($idListView, 2, "Download 3 is canceled!")
            EndSwitch
    EndSwitch
WEnd

Func UpdateDownloadInfo()
    _GUICtrlListView_SetItemText($idListView, 0, "Download 1: " & InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) / 1024 & "KB's is downloaded...")
    _GUICtrlListView_SetItemText($idListView, 1, "Download 2: " & InetGetInfo($hDownload_2, $INET_DOWNLOADREAD) / 1024 & "KB's is downloaded...")
    If $iDownloadCount == 3 Then
        _GUICtrlListView_SetItemText($idListView, 2, "Download 3: " & InetGetInfo($hDownload_3, $INET_DOWNLOADREAD) / 1024 & "KB's is downloaded...")
    Else
        _GUICtrlListView_SetItemText($idListView, 2, "Only two simultaneous downloads!")
    EndIf
EndFunc

 

The code is not prefect, but it's demonstrates the problem.

So, when I download more than 2 files simultaneous from one server (in my example I download 3 simultaneously) by InetGet() with background option, I will get only 2 active downloads. It's seems like server limitation. The third will remain with 0 read bytes until one of the previous downloads would finished. And if I want to close this third 0 bytes read download with InetClose() I will get hang of Window GUI for several seconds! After that, the third download would be closed and everything will continue to work normally.

If I InetClose() one of the active downloads with more than 0 bites read - all works fine!

You can try by your self given example, or watch this .gif's:

1. Window GUI hangs when I trying to Cancel (InetClose()) download with 0 bytes read download:

inetclose_hang_01.gif.66b1c93c1106af8b55379aff478dce50.gif

2. All works as it should, when I Cancel more than 0 bytes read download:

inetclose_hang_00.gif.182a30a2f3f5e17bdc8f425fececb2d0.gif

Any ideas why is it happens?

Link to comment
Share on other sites

I've tried to debug, maybe some error occurs, by adding this line to UpdateDownloadInfo():

ConsoleWrite(InetGetInfo($hDownload_1, $INET_DOWNLOADEXTENDED) & @CRLF & InetGetInfo($hDownload_2, $INET_DOWNLOADEXTENDED) & @CRLF & InetGetInfo($hDownload_3, $INET_DOWNLOADEXTENDED)& @CRLF & "--" & @CRLF)

I get only 0's every second from each of the downloads:

0
0
0
--

P.S. $INET_DOWNLOADEXTENDED or $INET_DOWNLOADERROR parameter in InetGetInfo() always return 0's...

Edited by Tersion
Link to comment
Share on other sites

So, I come up with more simple example of a problem with some measurements:

Spoiler
#include <InetConstants.au3>

Local $hDownload_1, $hDownload_2, $hDownload_3
Local $iStep = 0
Local $aFileName[3] = ["\1-BigBuckBunny_320x180.mp4", "\2-BigBuckBunny_640x360.m4v", "\3-big_buck_bunny_720p_stereo.ogg"]

$hDownload_1 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & $aFileName[0], $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
$hDownload_2 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v", @ScriptDir & $aFileName[1], $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
$hDownload_3 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_stereo.ogg", @ScriptDir & $aFileName[2], $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)

Sleep(5000)

Do
    If InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) == 0 Then
        ConsoleWrite("Waiting - $hDownload_1 is closing!" & @CRLF)
        $iTimer = TimerInit()
        InetClose($hDownload_1)
        ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms" & @CRLF)
    Else
        If InetGetInfo($hDownload_2, $INET_DOWNLOADREAD) == 0 Then
            ConsoleWrite("Waiting $hDownload_2 is closing!" & @CRLF)
            $iTimer = TimerInit()
            InetClose($hDownload_2)
            ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms" & @CRLF)
        Else
            If InetGetInfo($hDownload_3, $INET_DOWNLOADREAD) == 0 Then
                ConsoleWrite("$hDownload_3 is closing!" & @CRLF)
                $iTimer = TimerInit()
                InetClose($hDownload_3)
                ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms" & @CRLF)
            EndIf
        EndIf
    EndIf
    ConsoleWrite($iStep & @CRLF)
    Sleep(1000)
    $iStep += 1
Until $iStep == 10

InetClose($hDownload_1)
InetClose($hDownload_2)
InetClose($hDownload_3)

For $i = 0 To UBound($aFileName) - 1
    FileDelete(@ScriptDir & $aFileName[$i])
Next

 

What the script does - it's start simultaneously 3 downloads in background mode, each from one server. Wait for 5 sec to get some data from downloads. Then starts Do...Until loop with checks if one of downloads doesn't have any downloaded data: InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) == 0 and then take place InetClose() which in my tests always take around 10 SECONDS !!! If you change InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) == 0 to InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) > 0 then you will see that InetClose() for downloads which have something downloaded already takes around 3-4 MS !!!

The $iStep thing in Do...Until is just for some recall in console to see where loop stop and where he add +1 to $iStep every 1 sec.

Here some output from console:

If InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) == 0

Waiting $hDownload_2 is closing!
It took: 10016ms
0
1
... ; slightly removed iterations for more space
8
9

If InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) > 0

Waiting - $hDownload_1 is closing!
It took: 5ms
...

 

Link to comment
Share on other sites

Here slightly modified version of previous script. Now it informs in console how many KB is downloaded before InetClose() call...

#include <InetConstants.au3>

Local $hDownload_1, $hDownload_2, $hDownload_3
Local $iStep = 0
Local $aFileName[3] = ["\1-BigBuckBunny_320x180.mp4", "\2-BigBuckBunny_640x360.m4v", "\3-big_buck_bunny_720p_stereo.ogg"]

$hDownload_1 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", @ScriptDir & $aFileName[0], $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
$hDownload_2 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v", @ScriptDir & $aFileName[1], $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
$hDownload_3 = InetGet("http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_stereo.ogg", @ScriptDir & $aFileName[2], $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)

Sleep(5000)

ConsoleWrite("Download 1: " & InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) / 1024 & "KB while downloaded and still ongoing..." & @CRLF)
ConsoleWrite("Download 2: " & InetGetInfo($hDownload_2, $INET_DOWNLOADREAD) / 1024 & "KB while downloaded and still ongoing..." & @CRLF)
ConsoleWrite("Download 3: " & InetGetInfo($hDownload_3, $INET_DOWNLOADREAD) / 1024 & "KB while downloaded and still ongoing..." & @CRLF)

Do
    If InetGetInfo($hDownload_1, $INET_DOWNLOADREAD) == 0 Then
        ConsoleWrite("Waiting - $hDownload_1 is closing!" & @CRLF)
        $iTimer = TimerInit()
        InetClose($hDownload_1)
        ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms" & @CRLF)
    Else
        If InetGetInfo($hDownload_2, $INET_DOWNLOADREAD) == 0 Then
            ConsoleWrite("Waiting $hDownload_2 is closing!" & @CRLF)
            $iTimer = TimerInit()
            InetClose($hDownload_2)
            ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms" & @CRLF)
        Else
            If InetGetInfo($hDownload_3, $INET_DOWNLOADREAD) == 0 Then
                ConsoleWrite("$hDownload_3 is closing!" & @CRLF)
                $iTimer = TimerInit()
                InetClose($hDownload_3)
                ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms" & @CRLF)
            EndIf
        EndIf
    EndIf
    ConsoleWrite($iStep & @CRLF)
    Sleep(1000)
    $iStep += 1
Until $iStep == 10

InetClose($hDownload_1)
InetClose($hDownload_2)
InetClose($hDownload_3)

For $i = 0 To UBound($aFileName) - 1
    FileDelete(@ScriptDir & $aFileName[$i])
Next

Console output:

Download 1: 4807KB while downloaded and still ongoing...
Download 2: 0KB while downloaded and still ongoing...
Download 3: 6877KB while downloaded and still ongoing...
Waiting $hDownload_2 is closing!
It took: 10015ms
0
...
9

 

Edited by Tersion
Link to comment
Share on other sites

Hi Tersion,
I made little changes in your script, hope you'll like that.

#include <InetConstants.au3>

Global $URLsite = "http://download.blender.org/peach/bigbuckbunny_movies/"
Global $aFileName[1+3] = ["", "BigBuckBunny_320x180.mp4", _
   "BigBuckBunny_640x360.m4v", "big_buck_bunny_720p_stereo.ogg"] ; 1+3 to get rid of [0]
Global $hDownload[1+3], $iStep = 0

For $i = 1 To 3
   $hDownload[$i] = InetGet($URLsite & $aFileName[$i], @ScriptDir & "\" & $aFileName[$i], _
   $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
Next

Sleep(5000)

For $i = 1 To 3
   ConsoleWrite("Download " & $i & ": " & InetGetInfo($hDownload[$i], $INET_DOWNLOADREAD)/1024 & _
   "KB while downloaded and still ongoing..." & @CRLF)
Next

Do
   For $i = 1 To 3
      If InetGetInfo($hDownload[$i], $INET_DOWNLOADREAD) == 0 Then
         ConsoleWrite("Waiting - $hDownload_" & $i & " is closing!" & @CRLF)
         $iTimer = TimerInit()
         InetClose($hDownload[$i])
         ConsoleWrite("It took: " & Round(TimerDiff($iTimer)) & "ms to close" & @CRLF)
         ExitLoop
      EndIf
   Next
   ConsoleWrite($iStep & @CRLF)
   Sleep(1000)
   $iStep += 1
Until $iStep == 10

For $i = 1 To 3
   InetClose($hDownload[$i])
   FileDelete(@ScriptDir & "\" & $aFileName[$i])
Next

I'm not sure there is a valid handle for your empty download, because if you change one line of your script from :

InetClose($hDownload[$i])

to

$Result = InetClose($hDownload[$i])
MsgBox(0, "", "$Result = " & $Result)

You will see MsgBox displaying "False", which should mean the Handle isn't "found and closed" for your empty download, so maybe the InetClose() function shouldn't be used when your download returns 0 bytes (?)
Also look at the example in the help file, topic InetGetInfo :

; part of the online example, topic InetGetInfo :
; ...
; Retrieve details about the download file.
    Local $aData = InetGetInfo($hDownload)
    If @error Then
        FileDelete($sFilePath)
        Return False ; If an error occurred then return from the function and delete the file.
    EndIf

    ; Close the handle returned by InetGet.
    InetClose($hDownload)
 ; ...


Why the handle was not closed in the example when something went wrong ?

Also I'm not a big fan of the "==" in your script, at this line :
If InetGetInfo($hDownload[$i], $INET_DOWNLOADREAD) == 0

I thought "==" was used to compare two strings if they are equal and case-sensitive.
Now when we change "==" to a simple "=" all the ConsoleWrite is different lol

Hope other readers will share their thoughts with you about your script :)

Edited by pixelsearch
Link to comment
Share on other sites

pixelsearch,

Thanks for that constructive rework of my example! Now it's more clearer. I need more practice to handle that type of code-thinking. And for "==" vs "=" also. I check language reference and you are right!

What about $Result = InetClose($hDownload[$i]) - you can check this topic. For some reason it always return False. So I don't know if it appropriate for checking if handle of download is valid.

You say: " ... so maybe the InetClose() function shouldn't be used when your download returns 0 bytes (?) ". I also think about that, but why then InetClose() nevertheless executes of download termination? After 10 sec but still... And no @error's anywhere.

And that:

; part of the online example, topic InetGetInfo :
; ...
; Retrieve details about the download file.
    Local $aData = InetGetInfo($hDownload)
    If @error Then
        FileDelete($sFilePath)
        Return False ; If an error occurred then return from the function and delete the file.
    EndIf

    ; Close the handle returned by InetGet.
    InetClose($hDownload)
 ; ...

" Why the handle was not closed in the example when something went wrong ? "

Very good remark! Now I also ask myself the same question...

Ok, if I would don't use InetClose() for 0 bytes downloads, how can I terminate them then?

Also I've checked all available InetGetInfo optional data for 0 bytes download:

$INET_DOWNLOADREAD - 0
$INET_DOWNLOADSIZE - 0
$INET_DOWNLOADCOMPLETE - False
$INET_DOWNLOADSUCCESS - False
$INET_DOWNLOADERROR - 0
$INET_DOWNLOADEXTENDED - 0

And must admit that after changing "==" to "=", If statement True every loop and I get the same result of InetGetInfo() before InetClose() and after handle of 0 bytes download is closed.

Edited by Tersion
Link to comment
Share on other sites

@Tersion : thanks for your kind words.
So it seems you found a bug a few hours ago, in the other topic you mentioned (confirmed by mikell, aka "Soulful cat", best avatar on the Forum !)

You did great creating a ticket in Bug Tracker, concerning InetClose() . But now if InetClose() isn't reliable, there's no use in trying to understand why it takes 10 seconds using a bugged function, I guess we'll have to wait for a fix concerning this issue in a future AutoIt release.

You ask what to do to terminate your downloads if 0 bytes are returned, because you don't want to wait 10s to close them with the buggy function. If no empty file has been written on your hard drive. Why not doing nothing concerning this empty download (don't close anything if 0 bytes were returned) then restart it when you know there is only 1 ongoing download (the 2nd one has terminated) as your download server doesn't allow more than 2 simultaneous download.

Well you sure will have many tries to do (it seems you already made a lot !)
And concerning this other InetGet() function, which returns a handle OR a number of bytes downloaded when it succeeds, depending on a parameter found or not in the function call... best way to start troubles !

Good luck for your future downloads :)

 

Link to comment
Share on other sites

pixelsearch,

YES YES YES !!!

I found out why I get problems with this downloads. By default in Windows 7 (don't know, maybe in more late versions too) max connection per ONE server is only 2. As I can assume InetGet somehow related to Windows system settings and that's why it's allow only 2 simultaneous downloads with followed problematic 0 bytes downloads. So I started search how to increase this value and found out, that this Windows Register Keys do the trick:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPer1_0Server"=dword:00000010
"MaxConnectionsPerServer"=dword:00000010

This parameters increase max connections per ONE server to 10, so now I just could handle in my scripts this number of connections and do not come across with this 0-bytes downloads troubles!

This info needs to be added to InetGet() help reference!

I'm so happy to figure out this thing!

P.S. Here the .gif where I'M THE LORD OF MY DOWNLOADS! :D

manage_downloads.gif.03ee7087f94adc6a68a32bc3bd74a8db.gif

Edited by Tersion
Link to comment
Share on other sites

Now that's great news, bravo Tersion !
The following link explains the detailed procedure you did :

https://smallbusiness.chron.com/change-number-simultaneous-downloads-chrome-68984.html

And this is written at the end of the web page, important !

Tips :
Both the "MaxConnectionsPerServer" and "MaxConnectionsPer1_0Server" registry entries must have the same value -- 10, for example.
This registry tweak also increases the number of simultaneous downloads allowed in other Web browsers, such as Firefox and Internet Explorer [note : Daniel Hatter, who wrote the article, uses Chrome]

Warning :
Information in this article applies to Windows 8 and 7. It may vary slightly or significantly in other Windows versions.

Edited by pixelsearch
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...