Much ink (both physical and virtual) has been spent on configuring application pools in IIS. I'm not going to attempt to surpass that wisdom on how application pools are configured and how they should be configured. Probably the best, single source I'm personally aware of is Thomas Marquardt's blog. http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx
However where I will make an attempt; is what an application pool is actually doing. Over the years different versions of IIS, the .Net Framework, and the CLR have stored and used different configuration settings in different places. They also have different default behaviors. This has led me to attach debuggers to worker processes to get the running values of the thread pools in various attempts to determine what is actually going on. Often somebody has made a change to aspnet.config, web.config, machine.config, or the registry and is confused that what they thought would happen isn't happening. And not everybody is comfortable with attaching debuggers to running processes.
So I made a very primitive, simple tool that I hope can allow people to see what their application pools are actually doing. It is a single ASPX page, in plain next. No .DLL needed. Nothing to install. You can just copy the file into the web root of your application, hit it with a browser, and then delete the file.
I'm attaching the full ASPX page in the .ZIP file here: DOWNLOAD-ZIP-FILE
Here is the bulk of the C# code if you want to look at it separately.
// Get process information.
System.Diagnostics.Process myProcess = System.Diagnostics.Process.GetCurrentProcess();
Session["myProcessThreadCount"] = myProcess.Threads.Count;
Session["myProcessId"] = myProcess.Id;
Session["myProcessName"] = myProcess.ProcessName;
// Get thread pool information. ASPX didn't like declaring the variables as they were used in the methods.
int maxWorkerThreads = -1;
int maxIOThreads = -1;
int minWorkerThreads = -1;
int minIOThreads = -1;
int availableWorkerThreads = -1;
int availableIOThreads = -1;
System.Threading.ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxIOThreads);
System.Threading.ThreadPool.GetMinThreads(out minWorkerThreads, out minIOThreads);
System.Threading.ThreadPool.GetAvailableThreads(out availableWorkerThreads, out availableIOThreads);
int usedWorkerThreads = maxWorkerThreads - availableWorkerThreads;
int usedIOThreads = maxIOThreads - availableIOThreads;
Session["maxWorkerThreads"] = maxWorkerThreads;
Session["maxIOThreads"] = maxIOThreads;
Session["minWorkerThreads"] = minWorkerThreads;
Session["minIOThreads"] = minIOThreads;
Session["availableWorkerThreads"] = availableWorkerThreads;
Session["availableIOThreads"] = availableIOThreads;
Session["usedWorkerThreads"] = usedWorkerThreads;
Session["usedIOThreads"] = usedIOThreads;
// Get HttpRuntime information
Session["machConfDir"] = System.Web.HttpRuntime.MachineConfigurationDirectory;
Session["targetFramework"] = System.Web.HttpRuntime.TargetFramework;
Session["appDomainAppId"] = System.Web.HttpRuntime.AppDomainAppId;
Session["appDomainId"] = System.Web.HttpRuntime.AppDomainId;
Session["iisVersion"] = System.Web.HttpRuntime.IISVersion;
// Get Configuration Runtime Information
System.Configuration.Configuration myWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
System.Object preCast = myWebConfig.GetSection("system.web/httpRuntime");
System.Web.Configuration.HttpRuntimeSection myHttpRuntime = preCast as System.Web.Configuration.HttpRuntimeSection;
Session["AppReqQueueLim"] = myHttpRuntime.AppRequestQueueLimit;
Session["minFreeThreads"] = myHttpRuntime.MinFreeThreads;
Session["minLocalFreeThreads"] = myHttpRuntime.MinLocalRequestFreeThreads;