Wednesday, November 10, 2010

threadPools again

Here's a supremely annoying ThreadPool undocumented/under-documented feature that cost me hours.
If you have a resource you're using -- say a database connection -- and you want to limit the resource -- say because you have hard limit on the number of simultaneous database connections you can open -- then you can limit the number of simultaneous threads that a ThreadPool can open by using the SetMaxThread method:

ThreadPool.SetMaxThread(X,Y);

All good. Only:
-- under-documented feature: If you set the max threads less than the number of CPU cores on your system, the setting is ignored. That is, if you're running on a quad-core machine, and you set the max threads to be 2, the ThreadPool assumes you don't know what you're talking about, assumes it can think for you, and disregards your setting.

-- un-documented feature: if you set the max threads less than the number of cores, the max threads setting *doesn't* default to the number of cores, it's ignored completely. Basically, the ThreadPool doesn't default to the lowest possible value, but ramps up the max threads to whatever it feels like it wants to do.

This makes the ThreadPool mostly useless.

Look, if I'm writing an app that uses no resources except the CPU, that's great. But who writes apps that don't use any resources.
Moreover, most software developers don't have any control over the hardware on which their app runs. If I'm a typical line of business developer, I'm writing code that is set up to run on a server somewhere against a database. Likely, I have no control over the server. And it can be upgraded at any time.
In the days of virtualization, an administrator can update the number of CPU cores to a virtual machine on the fly. So if my app runs on a server, and an unrelated app runs on same server, and unrelated app needs more horsepower, admins can add CPU cores without even telling me.

If they do that, then all of a sudden my app -- which was throttled to a small number of threads so that it wouldn't smash the database connections -- now has the MaxThreads set too low. In that case, ThreadPool completely ignores the setting and spins off a zillion threads if it feels like the CPU can take it... completely crushing the database.

It's so frustrating when Microsoft does this. They make a great product, with a great feature, then make it totally unusable in real-world, line-of-business solutions.

GRRRRRRRRRRRR

--kevin