Multi-Threading Problem

G

Guest

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, 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
 
J

Jon Skeet [C# MVP]

Demetri said:
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, 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.


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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top