Does the ThreadPool reset the maximum threads after the code that sets it finishes? Should I manually do this?

c#, c#-3.0, multithreading, threadpool

Solution

TL;DR: Don't use `SetMaxThreads`.

This setting is per-process: Other processes are not affected, but your entire application is! This is called "a global solution for a local problem" and is considered a bad thing.

You want only some part of your app to be affected by this setting but you are affecting the whole app.

For example if you set max-threads to a low value to limit concurrency you will starve out the rest of the entire application including ASP.NET request threads and such.

For that reason I always prefer to solve such issues locally. Many TPL primitives (PLINQ, Parallel.*) allow you to set a max degree of parallelism. For simple tasks you can use a custom task scheduler which has a fixed number of threads (code available in the ParallelExtras).

Problem

I have written some (c# 3.5) batch processing code that can optionally override the thread pool maxthreads. It uses some pretty heavy resources that are not thread-safe, requiring a "resource pool" to be maintained with an item for each active thread. The consuming application can set a limit on how many threads the batch processor will use, which in turn calls `ThreadPool.SetMaxThreads()`. I'm doing this to test if manually setting a limit averages better performance than leaving it at the default setting. My question is, should I reset the maxthreads back to the previous value for the application after each use of the batch processing code? It will be called intermittently throughout the day, possibly thousands of times. Will the MaxThreads limit persist forever until the application is restarted / it is set to a different value, or will it automatically reset? While this isn't really a concern in my test harness, I'm wondering if I should update the code to "reset" the threadpool when the other resources are disposed after a batch completes for use in a production environment. Are there any implications to just leaving it overridden? Finally, does setting the threadpool in one .net application set it for ALL applications on the box, or only for the context of that single app?

Original source