Reputation: 527
I can;t seem to find an easy way to determine when a ThreadPool has finished with all the queued tasks. I found some answers here but none of which can help me.
For sake of simplicity let's say:
for (int i=0;i<10;i++)
{
threadpool.queueuserworkitem(Go);
}
void Go()
{
Console.WriteLine("Hello");
}
So how would I go about sending a final "All done" console.writeline after all the 10 background threads have finished?
Thanks
Upvotes: 5
Views: 4597
Reputation: 14734
You wouldn't ask the thread pool, but instead you would get each background thread to provide notification of when it completes.
But don't do that plumbing yourself, use the new TPL and the Task
class:
var tasks = new Task[10];
for (int i=0;i<10;i++)
{
tasks[i] = Task.Factory.StartNew( Go );
}
Task.WaitAll(tasks);
Console.WriteLine("All done");
void Go()
{
Console.WriteLine("Hello");
}
EDIT: I would question why you want exactly 10 threads performing the work. The default task scheduler already optimizes for the number of CPU cores detected. But if you must, there is an implementation of a TaskScheduler that limits the degree of concurrency to a fixed number here: http://msdn.microsoft.com/en-us/library/ee789351.aspx
Upvotes: 4
Reputation: 7259
Have you tried using Reactive Extensions?
Rx makes doing just this very simple. For example, you can rewrite your problem like this:
private void test()
{
var list = Enumerable.Range(0, 10)
.ToObservable()
.ObserveOn(Scheduler.ThreadPool)
.SubscribeOn(Scheduler.ThreadPool)
.Subscribe(i=>Go(),Done);
}
void Go()
{
Console.WriteLine("Hello");
}
void Done()
{
Console.WriteLine("Done");
}
Super simple. Look into Rx, you'll be glad
Upvotes: 1
Reputation: 2264
It is impossible and dangerous to rely on thread pool emptiness. What you can do is to count your active tasks yourself. A low level approach with monitor:
class Program
{
static object _ActiveWorkersLock = new object();
static int _CountOfActiveWorkers;
static void Go(object state)
{
try
{
Console.WriteLine("Hello");
}
finally
{
lock (_ActiveWorkersLock)
{
--_CountOfActiveWorkers;
Monitor.PulseAll(_ActiveWorkersLock);
}
}
}
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
lock (_ActiveWorkersLock)
++_CountOfActiveWorkers;
ThreadPool.QueueUserWorkItem(Go);
}
lock (_ActiveWorkersLock)
{
while (_CountOfActiveWorkers > 0)
Monitor.Wait(_ActiveWorkersLock);
}
Console.WriteLine("All done");
}
}
Upvotes: 0