I have an application I am writing that is using multiple threads to pull
down files from a web service. I want a thread to run for each file needed to
pull down. The code I have written works wonderfully. However, when I add in
the ability to control the number of threads running at any point in time to
be only 3 and then when one has finished another is started. So, if there are
15 files only 3 are being downloaded at the same time, when the first one has
finished another thread is started to get the next file. I then run into a
problem I am grappling with and need some help. The culprit is the while loop
in the code below:
for(int i=0; i<files.Length;i++)
{
while(threadsStarted >= maxThreads)
{
Thread.Sleep(50);
//hang tight for available thread to start
}
Interlocked.Increment(ref threadsStarted);
WorkerClass wc = new WorkerClass( this, showProgress, new object[] {
imsgs,files[i], decrementThreads } );
Thread t = new Thread( new ThreadStart(wc.RunProcess));
t.IsBackground = true; //make them a daemon - prevent thread callback
issues
t.Start();
EnableButton ( false );
}
When the threadsStarted reaches 3 it equals the maxThreads (which is set to
3 in code before this) then it is as if my threads stop running. I set a
break point in code that runs in the method the thread executes and it stops
at the point as long as threadsStarted variable is less than 3 but after that
it does not. So it seems like the while loop is suspending everything.
Any ideas how to correct this? I know I must be doing something wrong - I
just don't know what.
-Demetri
Jon Skeet [C# MVP] - 04 Dec 2004 19:11 GMT
> I have an application I am writing that is using multiple threads to pull
> down files from a web service. I want a thread to run for each file needed to
[quoted text clipped - 34 lines]
> Any ideas how to correct this? I know I must be doing something wrong - I
> just don't know what.
It looks like you're not getting threadsStarted and maxThreads in a
thread-safe way - see
http://www.pobox.com/~skeet/csharp/threads/volatility.shtml
for details.
I would suggest using a monitor and wait/pulse instead though, to tell
the thread when to run. There's no need to start a new thread each time
though - why not just start three threads and have a producer/consumer
type queue? (Alternatively, use a custom thread-pool with three threads
in.)
If you read through the article linked above (there are more pages than
just that one) you'll find details of all these approaches.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too