views:

334

answers:

4

I set the max thread to 10. Then I added 22000 task using ThreadPool.QueueUserWorkItem. It is very likely that not all the 22000 task was completed after running the program. Is there a limitation how many task can be queued for avaiable threads?

+2  A: 

The queue has no practical limit however the pool itself will not exceed 64 wait handles, ie total threads active.

keithwarren7
A bug caused my problem, but basically the answer for the question is this.
Andras
+3  A: 

From the documentation of ThreadPool:

Note: The threads in the managed thread pool are background threads. That is, their IsBackground properties are true. This means that a ThreadPool thread will not keep an application running after all foreground threads have exited.

Is it possible that you're exiting before all tasks have been processed?

Joey
+3  A: 

This is an implementation dependent question and the implementation of this function has changed a bit over time. But in .Net 4.0, you're essentially limited by the amount of memory in the system as the tasks are stored in an in memory queue. You can see this by digging through the implementation in reflector.

JaredPar
+5  A: 

If you need to wait for all of the tasks to process, you need to handle that yourself. The ThreadPool threads are all background threads, and will not keep the application alive.

This is a relatively clean way to handle this type of situation:

 using (var mre = new ManualResetEvent(false))
 {
      int remainingToProcess = workItems.Count(); // Assuming workItems is a collection of "tasks"
      foreach(var item in workItems)
      {
           ThreadPool.QueueUserWorkItem(delegate
           {
               // Replace this with your "work"
               ProcessTask(item);

               // This will (safely) decrement the remaining count, and allow the main thread to continue when we're done
               if (Interlocked.Decrement(ref remainingToProcess) == 0)
                      mre.Set();
           });
      }
      mre.WaitOne();
 }

That being said, it's usually better to "group" together your work items if you have thousands of them, and not treat them as separate Work Items for the threadpool. This is some overhead involved in managing the list of items, and since you won't be able to process 22000 at a time, you're better off grouping these into blocks. Having single work items each process 50 or so will probably help your overall throughput quite a bit...

Reed Copsey
Good idea, but the app was waiting for all threads. Grouping is also a very good suggestion.
Andras