ThreadPool wait for threads to finish

P

Peter Kirk

Hi there

I am looking at using a thread-pool, for example one written by Jon Skeet
(http://www.yoda.arachsys.com/csharp/miscutil/). Can anyone tell me if this
pool provides the possibility to wait for all its threads to finish?

For example, if I start 20 threads:

CustomThreadPool pool = new CustomThreadPool("PetersThreadPool");
ThreadMethod m = new ThreadMethod(InsertThread);
for (int i = 0; i < 20; i++)
{
pool.AddWorkItem(m, i);
}

[
where my thread method is:
delegate object ThreadMethod(int val);
private object InsertThread(int val)
{
Console.WriteLine("Thread " + val);
return 0;
}
]

How do I wait until all the threads are finished, before my program should
continue? Do I do this here:
while (pool.WorkingThreads > 0)
{
}

Thanks,
Peter
 
S

Shardool Karnik

just a thought ...

have each thread report to the main thread upon completion and then check
the thread count at that point to see if others are still running....instead
of a while loop
 
J

Jon Skeet [C# MVP]

Shardool Karnik said:
have each thread report to the main thread upon completion and then check
the thread count at that point to see if others are still running....instead
of a while loop

That would work - or make each thread "produce" on a semaphore, and
wait (from the main thread) until the semaphore had been hit the
appropriate number of times.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

If you want to execute them in sequence what you need to make a thread for?

what if you do this:
1- Create a queue with the correct delegates referencing the methods you
want to execute
2- Create a thread and start Pop-ing the delegates and executing in turn.

The only drawback may be that you cannot stop an individual item, you could
finish the thread but it would finish the entire execution, but you may find
other approach to execute the rest.


cheers,
 
J

Jon Skeet [C# MVP]

<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us> said:
If you want to execute them in sequence what you need to make a thread for?

He didn't say he wanted to execute them in sequence - he said he wanted
to wait until they were all done. That's perfectly reasonable. For
instance, you might be writing a web app which has to query several
different data sources, and you want to do that concurrently, but you
can't actually complete the request until all the separate queries are
complete.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

You are right, I have no idea where I get that idea from :)

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
 
H

Howard Swope

I needed to do the same thing and came up with the following solution. I
don't know how effective it is in all cases, but it worked in my situation.
private static AutoResetEvent AllThreadsDone = new
AutoResetEvent(false);

public static bool WaitForThreadPoolIdle(int timeout)

{

bool ret = false;



Thread threadMonitor = new Thread(new
ThreadStart(MonitorThreads));

threadMonitor.Start();



ret = AllThreadsDone.WaitOne(timeout,false);

if (!ret)

{

threadMonitor.Abort();

}

return ret;

}



private static void MonitorThreads()

{

int mwt, miot, awt, aiot;

ThreadPool.GetMaxThreads(out mwt, out miot);



// make sure all the thread pool threads are done working

awt = aiot = 0;

while(mwt != awt || miot != aiot)

{

ThreadPool.GetAvailableThreads(out awt, out aiot);

Thread.Sleep(0);

}

Thread.Sleep(0);

AllThreadsDone.Set();

}
 
P

Peter Kirk

James Swindell said:
Peter,

Are you opposed to creating a group of reset events?

No, I am not opposed to that if it would get the job done, but I have now
found a solution where I use a "counting semaphore". When I create a thread
I increment the semphore count, and each thread gets a reference to the
semaphore which it signals (decrements) when done, and in my main thread I
wait for the semaphore count to reach 0 again.

Thanks,
Peter
 
P

Peter Kirk

Howard Swope said:
I needed to do the same thing and came up with the following solution. I
don't know how effective it is in all cases, but it worked in my situation.
private static AutoResetEvent AllThreadsDone = new
AutoResetEvent(false);

public static bool WaitForThreadPoolIdle(int timeout)

<cut>

Hi, thanks for the suggestion. I have gone the "counting semaphore" route. I
just thought the thread-pool might offer an in-built wait-method or
something for that functionality.

Peter
 
P

Peter Kirk

Jon Skeet said:
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT


He didn't say he wanted to execute them in sequence - he said he wanted
to wait until they were all done. That's perfectly reasonable. For
instance, you might be writing a web app which has to query several
different data sources, and you want to do that concurrently, but you
can't actually complete the request until all the separate queries are
complete.

Yes, I am actually querying a search engine with a large number of search
requests while I process a large batch of documents. I'm hoping that by
splitting the batch of documents up into a number of threads each performing
searches on a smaller subset of documents then I can increase throughput
(actually I know I can), but I need to wait until all the searches/threads
are complete before I continue processing the documents batch.

Peter
 
P

Peter Kirk

Jon Skeet said:
That would work - or make each thread "produce" on a semaphore, and
wait (from the main thread) until the semaphore had been hit the
appropriate number of times.

This is the route I have taken (a "counting semaphore", which I increment
each time I start a thread, and which each thread decrements when finished -
the main thread then waits until the count is 0).

Actually I didn't quite understand the first proposal. By "report to the
main thread", is that an event or some other sort of messaging mechanism
which the main thread listens for - obviously some sort of non-busy
listening?

Thanks,
Peter
 

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