Personal computing discussed

Moderators: renee, SecretSquirrel, just brew it!

 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Multi-threading vb.net application

Sat May 02, 2009 2:40 pm

Hi gents,

I have a program that works 100% perfectly, except I think it could work better or more efficiently given it's resources in cpu cores as well as the amount of ram I can take advantage of. Basically this program reads a database that has 2 web file paths in it, 1 for each image, and I need to download that image. I have it working but it's limited to a file at a time, when I know that it's not saturating my bandwidth. So, what I'd like to do is multi-thread this but I am new to this and am wrapping my head around it.

Essentially, I am creating one giant record set (data reader) and then from there, for each record in it, attempt to download the image. I handle all errors gracefully by flagging the record if it can't download it it for any reason, then creating an error log for perusal later. Anyhow, I understand that in order to pass a thread any parameters, I need to wrap my sub or function call in a class, and create a new thread which is the class.method(params).

Moving on, I guess now I am a little gun shy - if I create 8 threads based on a for/next loop, and in that loop I call my class.sub(params) where the parameter is the two files to grab (1 record, 2 files), will it do everything 8 times (I think it would) or would the while loop increment itself preventing this somehow. How best to go about this?

thanks!
 
UberGerbil
Grand Admiral Gerbil
Posts: 10368
Joined: Thu Jun 19, 2003 3:11 pm

Re: Multi-threading vb.net application

Sat May 02, 2009 3:10 pm

Rather than creating an arbitrary number of explicit threads, you're almost certainly better off just using the threadpool. This is likely to be easier (and less error-prone) for someone new to threading, and has some performance advantages as well (there's overhead to creating and destroying thread, so just reusing the threads in the pool is cheaper, and the CLR will scale the number of threads according to the available cores though you can tweak that if you want). You can run through your recordset queuing up workitems and they'll get executed as resources become available.

I can go into this in more detail but I'm a little time-constrained ATM a bit of googling should turn up plenty of tutorials and sample code in VB demonstrating this.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Sat May 02, 2009 3:24 pm

Thanks for the input so far - I wouldn't have known to look for a pool of some sort but the thought did cross my mind on how precisely it was going to instantiate new threads - So in other words, If I don't set anything. I got my code to compile, not quite getting what I am expecting yet. Lots to learn. I'll post back here later this evening, I am beat. :)
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Sat May 02, 2009 3:56 pm

Should have just mentioned it, but I'm leaving the office asap. The problem I am having is probably a mix between not fully understanding threading yet, a race condition I think, and an error in logic.
While reader2.Read()
            Try
                Dim imageDownloaderThread As New SpawnDownloaderClass()
                ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SpawnDownloaderClass.downloadImage))
                SpawnDownloaderClass.barline = reader2.GetString(0)
                SpawnDownloaderClass.outside = reader2.GetString(1)
                SpawnDownloaderClass.inside = reader2.GetString(2)
            Catch ex As Exception
                Dim logLocation = "\\SERVER\projects\FOLDER\errorLogs\" & Now.ToString & ".txt"
                Dim errLog As New StreamWriter(logLocation, True)
                errLog.WriteLine(ex.ToString)
                errLog.Close()
            End Try
            Thread.Sleep(1000)
        End While


So this works, but my error logs get generated. I think what I have done is incorrect - the logs are just saying that the file already existed so it's downloading duplicates I believe. My real problem is in logic I think. I pass 3 values to my class method that I need to download the image and write an error log if it fails. What I want to do is for each record in the data reader, attempt to download the image. I want it to do this per thread until the pool is used so that I am trying to retrieve X files at a time where X is the max threads it gives me from the pool. I think I need to do some sort of record traversing so that it hits the next record. Also, the way it's currently running gets everything the lasts records 2 images - they start to download but fail because the main exists - I put the sleep in there to prevent the initial race condition but now what?
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Multi-threading vb.net application

Sat May 02, 2009 4:42 pm

Before we go any further, what makes you think that using more threads will result in better performance? The big win for multi-threading is on tasks which are CPU-limited; there's no way downloading files from the web is CPU-limited unless you've got a really fat pipe to the Internet (like 100 mbit or better).

The only way I can imagine this helping to any great extent is if you're downloading from multiple different sites, and are being limited by the bandwidth at the server end (i.e. you're saturating the upload bandwidth of the sites you're downloading from).

Edit: I've done very little VB, so I may be mis-reading your code here. But it appears to me that you're using the same set of variables to pass the file name information to all of the threads (maybe this is the race condition you're referring to). This could explain why multiple threads seem to be trying to download the same file -- the variables are getting stepped on by the next iteration through the loop (when starting the next thread), before the thread spawned on the previous iteration has finished using them. You probably ought to be using the other form of QueueUserWorkItem() -- the one which allows additional data to be passed directly to the spawned thread.

I suspect there may also be some issues with the way you're doing exception handling; you probably should be handling exceptions in the spawned threads in addition to (or possibly instead of) in the parent thread. This means you'll also need to somehow coordinate access to the log file, or the error messages from the different threads may step on each other.

As I said, I haven't done much VB, so take the above with a grain of salt. (I've done *tons* of multi-threaded programming in C/C++ though, so I can generally spot the sort of race conditions that lead to weird behavior in multi-threaded apps...)
Nostalgia isn't what it used to be.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Sat May 02, 2009 5:01 pm

Ok here's my reasoning:

The current method only allows me to download 1 image at a time from the machine the code resides on. Knowing full well that I am not saturating the bandwidth of that server, my network, or the server I am pulling from, I figured I could spawn a few more instances to download a few more images concurrently thus speeding up the entire process. We do have a fat pipe but how fat I don't know off hand, I also suspect my server is throttled severely but that can change.

So then it sounds like what you're saying is that spawning a new thread isn't going to do anything worth while. Again, what I am trying to accomplish is to be able to download as many images concurrently as possible. These are small images, they generally take 3-10 seconds to download at best I would imagine, but the current code that I am writing gets them one at a time, and waits for each one to finish before grabbing the next one in the record set. My thought process was such that if I could delegate 8 threads to the first 8 records for example, and so on, that I'd be much better off.

Is there a reliable testing method (software, website, whatever) to see if there is a bottleneck on the server I am downloading from? That server is out of my control, just curious. I mostly program for the web so threading is certainly not something I do very often, nonetheless I'd like to continue the discussion about my idea if it's remotely possible / worthwhile.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Sat May 02, 2009 5:14 pm

just brew it! wrote:

Edit: I've done very little VB, so I may be mis-reading your code here. But it appears to me that you're using the same set of variables to pass the file name information to all of the threads (maybe this is the race condition you're referring to). This could explain why multiple threads seem to be trying to download the same file -- the variables are getting stepped on by the next iteration through the loop (when starting the next thread), before the thread spawned on the previous iteration has finished using them. You probably ought to be using the other form of QueueUserWorkItem() -- the one which allows additional data to be passed directly to the spawned thread.

I suspect there may also be some issues with the way you're doing exception handling; you probably should be handling exceptions in the spawned threads in addition to (or possibly instead of) in the parent thread. This means you'll also need to somehow coordinate access to the log file, or the error messages from the different threads may step on each other.

As I said, I haven't done much VB, so take the above with a grain of salt. (I've done *tons* of multi-threaded programming in C/C++ though, so I can generally spot the sort of race conditions that lead to weird behavior in multi-threaded apps...)


You're right about the variables, I was going to re-examine my logic later, but if my entire idea is boned, I was going to try something else. This is all really spur of the moment and I was kinda coding as I went. The race condition only affects the absolute last file it processes.... So is my idea still a bit off? Here's some pseudocode...

' pseudo-code
while myRecordset.Read 'loops and processes each record one at a time, forward only through the Database (sql)
  create a thread and pass it the first record
  another thead and second record
  etc
end while

Now clearly what it will do instead and what I am pretty sure I am doing wrong at this point is that for each record, it's sending record 1 to each of the threads 1 time, and so on. So if I have 5 records, and 5 threads, 25 times. Surely wrong but I'm just working from a concept here.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Tue May 05, 2009 5:25 pm

So I got the multi-threaded part correct, and because I don't want the system to manage the threads, I created my own thread management because I am concerned with bandwidth saturation and diminishing returns. Basically, I get a datareader that contains all the files I need to download from the remote server, and for each thread up to my threadLimit variable I add the files to download and continue. The results are promising but not 100% yet. What happens is that I see all of my test files immediately land with 0k for the data. Following that, they download 2 at a time for reasons unknown to me. I know I'm not saturating my bandwidth and the server is likely not being taxed, so why only 2 at a time on the download?

So if I can be positive my threads are all being created, if the action per thread is to create a new file request and read the stream and build a file, why would it do it 2 at a time?
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Multi-threading vb.net application

Tue May 05, 2009 6:09 pm

It is not uncommon for web servers to be configured to allow only 2 downloads at a time from the same IP address.
Nostalgia isn't what it used to be.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Tue May 05, 2009 7:28 pm

I would agree except that today due to the slowness we had been experiencing, we contacted someone in the know and they suggested exactly what I had just done, I don't see the benefit of all that extra programming for 1 extra download instance, seems kinda frivolous. I'm not going to undo it thought because given how many images per file batch (we're talking thousands and thousands here), it'd be worth it. There has to be a better way.
 
notfred
Maximum Gerbil
Posts: 4610
Joined: Tue Aug 10, 2004 10:10 am
Location: Ottawa, Canada

Re: Multi-threading vb.net application

Wed May 06, 2009 8:21 am

just brew it! wrote:
It is not uncommon for web servers to be configured to allow only 2 downloads at a time from the same IP address.

Also web browsers - see http://www.die.net/musings/page_load_time/ which has the suggestion of spreading this over multiple hostnames to overcome this.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Wed May 06, 2009 8:33 am

I'm still hesitant to believe that the browsers have anything to do with this. I've got a brand new server with only IE 7 or 8 on it, and I've done the reg hacks to allow more downloads. That's not to say that my code isn't working as I think it is, or any other phantasm :)

Here are the two ways I am attempting to download, again, these 2 processes are performed in their own thread, and obviously I only choose one of them
The first seems much more likely to cause problems with this 2 file limit per browser / HTTP settings. Both ultimately end up with the same result.

I'd be happy to post my entire code, it's not that large, but I have to scrub it first, sensitive data etc.
'create web request, read response as array of bytes, write to a file, close stream, close file
Dim request As HttpWebRequest = WebRequest.Create(strImage)
Dim response As HttpWebResponse = request.GetResponse

' -OR -

'I enabled this in an earlier test with the UI on so I could watch the downloads, all at once my downloads all pop up, but only 2 are downloads at a time.
My.Computer.Network.DownloadFile(requestImagePath, SaveToPath)
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Multi-threading vb.net application

Wed May 06, 2009 8:34 am

steelcity_ballin wrote:
I would agree except that today due to the slowness we had been experiencing, we contacted someone in the know and they suggested exactly what I had just done, I don't see the benefit of all that extra programming for 1 extra download instance, seems kinda frivolous.

Unless the person you contacted is very familiar with how this particular server was configured, he may not realize that there's a 2 stream limit.

I wouldn't worry about it. If you're getting any benefit from the multi-threading at all, you're probably already getting most of it with just the 2 threads. Adding more threads will probably result in diminishing returns, or even start to hurt.
Nostalgia isn't what it used to be.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Wed May 06, 2009 8:43 am

just brew it! wrote:
steelcity_ballin wrote:
I would agree except that today due to the slowness we had been experiencing, we contacted someone in the know and they suggested exactly what I had just done, I don't see the benefit of all that extra programming for 1 extra download instance, seems kinda frivolous.

Unless the person you contacted is very familiar with how this particular server was configured, he may not realize that there's a 2 stream limit.

I wouldn't worry about it. If you're getting any benefit from the multi-threading at all, you're probably already getting most of it with just the 2 threads. Adding more threads will probably result in diminishing returns, or even start to hurt.


Given the small file sizes (the largest I've seen is 4mb across 30,000 images), I believe that I can safely do about 5 without saturating my bandwidth and that is about the point of diminishing returns where as the number of downloads increases, the rate at which I download will decrease to a point of inefficiency. I would estimate that a good sample range for file size is from 500k - 2.5mb. I've seen a few smaller, and a few larger but that large majority fall in that range. notFred and JBI - YHPM.
 
Flying Fox
Gerbil God
Posts: 25690
Joined: Mon May 24, 2004 2:19 am
Contact:

Re: Multi-threading vb.net application

Wed May 06, 2009 9:03 am

steelcity_ballin wrote:
I'm still hesitant to believe that the browsers have anything to do with this.

It's not the browsers (client end) but on the server side.

Actually, the best way is to zip all these small files up and serve up that one bigger file (or 2). Is it possible?

BTW, your download program is a standalone GUI app, right? Can I see what you have now in terms of spawning the threads and controlling them?
The Model M is not for the faint of heart. You either like them or hate them.

Gerbils unite! Fold for UnitedGerbilNation, team 2630.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Wed May 06, 2009 9:36 am

Flying Fox wrote:
steelcity_ballin wrote:
I'm still hesitant to believe that the browsers have anything to do with this.

It's not the browsers (client end) but on the server side.

Actually, the best way is to zip all these small files up and serve up that one bigger file (or 2). Is it possible?

BTW, your download program is a standalone GUI app, right? Can I see what you have now in terms of spawning the threads and controlling them?


Zips files are not an option. Yes it's stand alone, I'll post what I can in a bit after I clean it up and take out the sensitive info. Thanks!
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Multi-threading vb.net application

Wed May 06, 2009 11:07 am

I'm still not convinced that we're even looking at the right problem here.

With files averaging around 1 MB in size, even a single stream ought to be able to make pretty good use of a 10 mbit (per your PM) pipe, unless the ping times really suck.

Before we potentially waste a lot of time chasing a red herring, it would be helpful if you could at least do the following:

- Check your ping times between the system doing the downloading and the server.

- Measure what sort of net throughput you are getting, both with 1 stream and with 2 streams.

- Verify that the server you're pulling from doesn't cap the number of download streams at 2.
Nostalgia isn't what it used to be.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Thu May 07, 2009 7:59 am

You're right not to be convinced. We *are* saturating our bandwidth per image, so threading will do nothing. I wish I had known / fully understood that days ago. Not much else I can do.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Multi-threading vb.net application

Thu May 07, 2009 8:52 am

Well, at least now you won't waste any more time on it. And you learned a little bit about multi-threading and networking, so it wasn't a complete waste regardless.
Nostalgia isn't what it used to be.
 
notfred
Maximum Gerbil
Posts: 4610
Joined: Tue Aug 10, 2004 10:10 am
Location: Ottawa, Canada

Re: Multi-threading vb.net application

Thu May 07, 2009 8:53 am

Either get a bigger pipe or give Akamai a call, that's about it :-(
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Fri May 08, 2009 7:10 am

just brew it! wrote:
Well, at least now you won't waste any more time on it. And you learned a little bit about multi-threading and networking, so it wasn't a complete waste regardless.


I agree, it's been a good refresher on some things, and a tad more eye opening to others. One thing I am still iffy on was something that I took for granted and am not sure how precisely it's working. Here we have a the aforementioned 10mb connection. At home I have about a 20mb connection but generally see 15ish during peak hours. Now clearly my connection at home is only supporting 1 user, here it's approximately 150 users. So 2 things, the pricing is of course vastly different for these lines at work - and my guess is that between the uptime guaranteed aka reliability coupled with the same down and upload speeds, that's the biggest difference.

Beyond Price, my biggest mental roadblock is that I know tons of people here download crap all day long, stream music, youtube, etc. If that was really happening all over as I think it is, shouldn't our measly 10mb get eaten up pretty quickly? I mean, my access is unlimited and I'm unfiltered so I don't know what other users experience but I would think that 10mb wouldn't be sufficient to support us, yet it seems to be. If I start downloaded something at near 1MB/s right now, should that reduce everyone else to downloading at near nothing? If that was the case, it would take like 2-3 users to eat up everything tops and cripple our downloads, and yet we have no issues like that so that can not be correct.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Multi-threading vb.net application

Fri May 08, 2009 8:05 am

Depending on how sophisticated your router is, there may be some QoS (Quality of Service) settings which have been configured to prioritize the traffic.
Nostalgia isn't what it used to be.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Fri May 08, 2009 8:49 am

just brew it! wrote:
Depending on how sophisticated your router is, there may be some QoS (Quality of Service) settings which have been configured to prioritize the traffic.


If what the gents here say is correct, the server I use has a guaranteed 5mb, and will use more if it needs it up to the max. If my new code is running correctly, for 1000 files, 2000 images, I averaged 850KB/s which is calculated after the files are downloaded so as to not add overhead to the download itself.
 
steelcity_ballin
Gerbilus Supremus
Topic Author
Posts: 12072
Joined: Mon May 26, 2003 5:55 am
Location: Pittsburgh PA

Re: Multi-threading vb.net application

Mon May 18, 2009 2:27 pm

So I am revisiting this in theory today because something is still bugging me about the nature of networks and saturating my download availability. We have a 10mb connection. We have about 150 uses on this network at a given time, all doing their own thing. Let's say that very conservatively, 5 of them, and only 5 are download anything. I don't care if it's streaming radio or whatever. If what I am understanding is correct, that should saturate our bandwidth for a 10mb connection and kill our network, yet I can browse on my machine just fine and download anything I want without issue.

What made me bring this up is that instead of threading the code (which i've already done), I put the same code on 2 separate machines and it runs at about the same speed. If what was said is true, they should be running at about 50% speed though, and clearly this isn't the case. So in reference to my first paragraph, why is it that running them 2 at a time on 1 machine is slower than 1 at a time on 2 machines!?! I have some fundamental misunderstanding about this stuff, I've got to.
 
Evaders99
Gerbil First Class
Posts: 154
Joined: Fri May 16, 2008 10:48 am
Contact:

Re: Multi-threading vb.net application

Mon May 18, 2009 4:35 pm

What is the data rate on your two machines? Is it actually saturating your 10 MB link?
 
rampatter
Gerbil In Training
Posts: 1
Joined: Tue Apr 10, 2012 1:14 pm

Re: Multi-threading vb.net application

Tue Apr 10, 2012 1:17 pm

EDIT BY MOD - Captain Ned - SPAM necro removed & banned. Post retained to explain necro.
 
frumper15
Gerbil XP
Posts: 380
Joined: Mon Jan 18, 2010 3:25 pm

Re: Multi-threading vb.net application

Tue Apr 10, 2012 4:16 pm

So I'm definitely posting outside my league here - definitely not my expertise - but bandwidth and download speed are a lot more than just the max width of you incoming pipe. Is it possible the server you're downloading from is saturating its upload bandwidth? Is that server possibly serving these same files to multiple other users and you are actually seeing a storage system bottleneck? That's really it, in my mind - where's the bottleneck? If you have a high ping/latency, but have good sequential transfer, i can see where multi-threading/simulaneous downloads could potentially speed things up, but if it's something else that is actually limiting your downloads, for example a storage system bottleneck, having too many threads trying to download could actually slow down your overall progress.

I think of it this way - on my home machine, it used to be if I was copying files across the network, a single transfer over gigabit could approach 100Mb/s (of mb or mbit - not sure). However, if I started two, it was down to less than 50 each - more like 25-30 mb/s as the drive was thrashing all over to attempt to satisfy both demands at once. I'm assuming you've got a higher class of hardware at work here, but the concept still applies - if you've got potentially 150 users hitting that same storage server for 100 different things at any given time, a 10MB pipe might be the least of your worries. Maybe this could justify an upgrade to some SSD storage at the server - they do wonders for multiple access speeds.

Have you tried a test environment where the source "server" was on the same network, connected over gigabit, or even force it down to a 10 meg connection to simulate your internet pipe and see what happens? That might be a fairly telling experiment for you.
i7-8086K | Z370 AORUS GAMING WIFI | 32GB DDR4-2400 | EVGA GTX 1080 Ti | 512GB 960 Pro | 27" Dell 2560x1440 Gsync | Fractal R6 | Seasonic Focus Plus 850W | Win10 Pro x64.
 
UberGerbil
Grand Admiral Gerbil
Posts: 10368
Joined: Thu Jun 19, 2003 3:11 pm

Re: Multi-threading vb.net application

Tue Apr 10, 2012 4:59 pm

Not sure why this thread got necro'd but please note it's almost three years old.

Who is online

Users browsing this forum: No registered users and 1 guest
GZIP: On