Know When ThreadPool Is Empty

I cannot find an easy way to determine when ThreadPool finished with all the queued tasks. I found several answers here, but none of them can help me.

For simplicity, we say:

for (int i=0;i<10;i++) { threadpool.queueuserworkitem(Go); } void Go() { Console.WriteLine("Hello"); } 

So, what should I do with sending the final “Everything done” console.writeline after the completion of all 10 background threads?

thanks

+4
source share
3 answers

It is impossible and dangerous to rely on the emptiness of a thread pool. What you can do is take your active tasks yourself. 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"); } } 
0
source

You do not ask for a thread pool, but instead, you will receive each background thread for notification of completion.

But do not do this 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 doing the work. The default task scheduler already optimizes the number of detected CPU cores. But if you need, there is an implementation of TaskScheduler that limits the degree of concurrency to a fixed number here: http://msdn.microsoft.com/en-us/library/ee789351.aspx

+3
source

Have you tried using Reactive Extensions ?

Rx makes it very simple. For example, you can rewrite your problem as follows:

  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 at Rx, you'll be glad

+1
source

Source: https://habr.com/ru/post/1398341/


All Articles