views:

386

answers:

2

Hi

Here is my app status:

Purpose - download multiple list files from internet Approach - created a simple "download form". After a while, I just needed more forms because I had more than one list of files to download. Just solved that by adding a MDIform to my project, add a button to create another "download form" instance and voilà. Apparently, my problem was solved. But no :(

When I press my "download" button in my form-instance3, the other form instances (2 and 1) hangs on downloading the contents (I get a timeout sometimes) until the form-instance3 terminates all the downloads and so on, for all the other forms. So, even though I know my app is not multi-threaded, the multiple instances of the same form are in conflict (Inet component, presumably) and I can't download multiple files at the same time. Inet and my download function are defined in the form.

What can I do to solve this? how can I download multiple files at the same time?

Many thanks

edit:

I'm trying to use the "wqw" suggestion, but I'm facing some problems: In the download_form, I have a MSHFlexgrid, with 2 columns: one with the URL and the other with the file destiny. I was iterating throw all rows to download the files and save them. With the approach suggested by "wqw", how can I distinguish each download so that I can save it with the properly name indicated in the grid?

+3  A: 

What do you use for the actual http download? I would try Simple Asynchronous Downloads and forget about the MDIForm. Really!

wqw
+1 This Karl Peterson article explains the little-known, simple **100% native VB6** way to do asynchronous downloads, with full sample code. This answer definitely deserves the bounty - accept no substitutes.
MarkJ
I'm trying this approach. Now, my problem is: by knowing that I have in a grid the pair "URL-file name destiny", how can I associate the bytes downloaded that are returned to the event "DownloadComplete" to the file name where I want to save the data? Thanks
Armadillo
+2  A: 

VB6, on its own, is single threaded. So breaking out downloading to different forms won't help you.

What I've used in the past is the Timer object in conjunction with an ActiveX EXE. This approach will give you an ability to localize all the downloading logic in one place, control it like you control a regular object and have it run in a separate EXE, thus by default making it multi-threaded.

So the way this works is like so:

  1. You call the Download method on the ActiveX EXE object
  2. In the download method, you instantiate the Timer and have it kick off almost immediately.
  3. You get out of the Download method, thus giving control back to the entity that called it.
  4. Then you communicate back to the main app via Events (e.g. DownloadProgress or DownloadComplete, etc...)
AngryHacker
+1 you explained why Armadillo's code doesn't work and gave a simple workaround. good answer.
DaveParillo
Good answer in general for asynchronous processing in VB6. But for internet downloads, wqw's answer is better: just use the native VB6 technique for asynchronous downloads.
MarkJ
@MarkJ I disagree, if @armadillo wants to be doing async or multithreaded programming in VB6, he/she better get the pattern, I described, down. If all you want to do is download files, then yes, AsyncRead makes sense. The AsyncRead thing is cool, but you are stuck with it only working in a UserControl - meaning if you wanted to centralize your logic in an ActiveX DLL (my choice for code separation), you are out of luck.
AngryHacker