Process a list of items using multiple, limited number of threads
Basically, I want to process a list of items in multiple threads instead of one at a time. I only want a limited number of threa开发者_运维问答ds going at a time. Does this approach make sense? Is using a global variable for the thread count the only option? (pseudo-code below)
foreach item in list
while thread_count >= thread_max
sleep
loop
start_thread item
thread_count++
next
function start_thread(item)
do_something_to item
thread_count--
end function
I would use PLINQ for this and specify a max degree of parallelism like so:
I'm actually changing my answer on this one because I realized you just want to process a raw list directly and you're not doing any other filtering or mapping (Where/Select). In this particular case it would be better to use Parallel::ForEach and specify the MaxDegreeOfParallelism via ParallelOptions like so:
int myMaxDegreeOfParallelism = 4; // read this from config maybe
Parallel.ForEach(
list,
new ParallelOptions
{
MaxDegreeOfParallelism = myMaxDegreeOfParallelism
}
item =>
{
// ... your work here ...
});
Now, keep in mind, when you specify a max like this you prevent PLINQ from being able to use any more resources even if they're availabe. So if this ran on an 8 core machine, it would never utilize more than 4 cores. Conversely, just because you specified 4, doesn't mean 4 are guaranteed to execute simultaneously at any given time. It all depends on several heuristics that the TPL is using to be optimal.
It makes sense, but I hope you're aware that this isn't the usual way to do it unless you have very specific performance reasons or are stuck on .NET 3.5. Normally you would use Parallel.ForEach
over the elements in the list, and rely on the partitioner to divide up the work into appropriate chunks.
Even if you didn't have the TPL, it would be more idiomatic to divide up all the work and hand each thread a big chunk of work at once, rather than doling it out piecemeal at the moment a thread finishes. The only reason to do it your way is if you expected the amount of time a given work item takes to be more or less unpredictable, so you couldn't divide up the work well in advance.
(Also, you could just keep references to the threads and check how many are still working and how many are completed. That would do away with the variable.)
精彩评论