It was then tested in the IDE as well as compiled with the following results:
Start Thread1 33381.81
Start Thread2 33382.23
End Thread2 33382.27
End Thread1 33382.32
Download 1 is a 180 KB jpg file - elapsed time 510 ms
Download 2 is a 1 KB page file - elapsed time 40 ms
Thread2 using https:
Start Thread2 33715.95
End Thread2 33716.29 - 340 ms
Note: I found "exename" to be unreliable, so the executable name is located in the Project Properties Version Information under File Description. If you change the executable name, be sure to change the File Description as well.
J.A. Coutts
Updated: 09/18/2023 - See post #12 for details.
Last edited by couttsj; Sep 18th, 2023 at 11:09 AM.
Maybe download it in chunks? What if a 1GB file takes 40 seconds to download, and uses 10 threads to download, and the time is only 4 seconds?
Wishful thinking, but very difficult to accomplish. When a client connects to an http server (port 80/443), the client selects an available port on its end to use for that connection. The server port (80/443) is listening, and if it accepts the connection request, the connection is transferred to an available port on it's end. The server then sends small packets of data (1500 bytes using ethernet) that may be received out of order. Each packet contains a header that allows the data to be restored in the correct order within the TCPIP buffer. To send and receive larger chunks of data over multiple ports would require the same type of coordination between the client and the server, and we have no control over the server.
I'm pretty sure downloading data in chunks has been implemented a long time ago, otherwise it wouldn't be possible to resume an interrupted download. I remember this was indeed the case during the Dial-Up days when you had to start over with your download when your connection was interrupted for some reason. Then the "GetRight" app was invented and it was a game changer. Later on every browser would adopt this technology.
More than 20 years ago, the Internet speed in China was only 56kb moden.
We have this kind of network ant, the download tool of Internet Express.
Does he have multithreading? I don't know.It can be downloaded in blocks, for example, a 10 megabyte file can be downloaded in 10 parts. Each one is like 10 kegs.After downloading a piece, the bucket is filled with water, and the effect is really very powerful.
When I first started learning programming, I didn't think I could do such a thing at all. I could only envy it.
Last edited by xiaoyao; Sep 10th, 2023 at 08:03 PM.
Resuming a download is nothing like downloading chunks on different threads. The problem is that threads will complete randomly, and a mechanism must exist to save them in the correct order.
I discovered that the program would crash after several downloads. I assumed that the problem was the fact that each time a download was run, a new handle to the thread was created. So I ran the CreateThread command only on the first run, and directly called the thread on subsequent runs. That corrected the crashing issue, but then I discovered that the threads did not run concurrently after the first run. So then I ended the thread by using this command structure:
Code:
Private Sub Command1_Click()
If mHandle1 = 0 Then Call TerminateThread(mHandle1, ByVal 0&)
mHandle1 = CreateThread(ByVal 0&, ByVal 0&, AddressOf Thread1, ByVal 0&, 0&, lpThreadId1)
End Sub
That fixed things in the IDE, but then I discovered that once compiled into an executable, an empty form would display when the thread was started, and that prevented me from testing the compiled version further.
I am at a loss as to how to proceed.
J.A. Coutts
Last edited by couttsj; Sep 17th, 2023 at 08:31 AM.
I discovered that the program would crash after several downloads. I assumed that the problem was the fact that each time a download was run, a new handle to the thread was created. So I ran the CreateThread command only on the first run, and directly called the thread on subsequent runs. That corrected the crashing issue, but then I discovered that the threads did not run concurrently after the first run. So then I ended the thread by using this command structure:
[code]
Private Sub Command1_Click()
If mHandle1 = 0 Then Call TerminateThread(mHandle1, ByVal 0&)
mHandle1 = CreateThread(ByVal 0&, ByVal 0&, AddressOf Thread1, ByVal 0&, 0&, lpThreadId1)
End Sub
[/code}
That fixed things in the IDE, but then I discovered that once compiled into an executable, an empty form would display when the thread was started, and that prevented me from testing the compiled version further.
I am at a loss as to how to proceed.
J.A. Coutts
dim exeok as long
SUB MAIN()
if exeok=1 then exit sub
exeok=1
form1.show
end sub
This behavior was also documented in my ActiveX MultiThreading example that you may have looked over:
Code:
Public Sub Main()
If Not App.TaskVisible Then Exit Sub ' Additional threads are re-entrant, meaning they will always execute the "Sub Main" so just exit the sub
frmVBMultiThreading.Show
End Sub
The Standard EXE approach doesn't need this since the additional threads are running in different processes.
The program became unstable and crashed after several downloads. I also had not yet confirmed that the threads operated concurrently beyond the first run. Since it was suspected that creating multiple handles was causing the problem, the old handle (thread) was deleted before creating a new one.
The download start and stop times were moved from the Immediate window to the text box on the form, so as to permit viewing of speeds in the executable. To verify that downloads are occurring concurrently, you will need to change one of the downloads to a bigger file in order to give yourself sufficient time to start another download. Because processor speeds are much faster than network speeds, using this methodology will tell you if you can run 2 downloads at the same time, but not necessarily if you are using 2 separate cores (hyper-threading). I am sure that it must be possible, but I don't know how to do that yet.
Running multithreading in the VB6 IDE is inherently unstable, if VB forms and other objects are not involved, pure API and add, subtract, multiply and divide running is stable.
If you have too much code, it might crash. If three threads display the result at the same time, for example:
form1.list1.additem info, the program may also crash. Add with SENDMESSAGE, ide will also crash, compiled into the EXE will not crash.
You can add three lable controls, and then each thread downloads 1%, 2% can be displayed.
Attached is a further simplified version of the same program. To use this program, you must first compile it and save it in the same directory as the code. Instead of downloading files, the threads execute long do loops. This was done to make the CPU cores work hard so they will display in the Resource Monitor.
Open the Resource Monitor and click on the CPU tab. This should display graphic images of the CPU cores that you have available. Now start the executable that you created called Download.exe. Go back to the Resource Monitor and find Download.exe in the list of threads. It is constantly changing, so quickly click on the box beside the name. This will move the file to the top of the list. Now go back to the Download window and quickly click on the command boxes in reverse order (Run4, Run3, Run2, Run1). You should see the results in some of the core displays. You will also see the Start and End times in the Download window. This is what I saw on my PC, along with the elapsed times I calculated:
Start Thread4 46164.59
Start Thread3 46165
Start Thread2 46165.61
Start Thread1 46166.19
End Thread1 46167.77 (1.6 sec)
End Thread2 46168.69 (3.1 sec)
End Thread3 46171.12 (6.1 sec)
End Thread4 46176.59 (12.0 sec)