2 out of 49 rated this helpful Rate this topic

ThreadPool Class

Updated: October 2010

Provides a pool of threads that can be used to execute tasks, post work items, process asynchronous I/O, wait on behalf of other threads, and process timers.

System.Object
  System.Threading.ThreadPool

Namespace:  System.Threading
Assembly:  mscorlib (in mscorlib.dll)
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
	ExternalThreading = true)]
public static class ThreadPool

The ThreadPool type exposes the following members.

  Name Description
Public method Static member BindHandle(IntPtr) Obsolete. Binds an operating system handle to the ThreadPool.
Public method Static member BindHandle(SafeHandle) Binds an operating system handle to the ThreadPool.
Public method Static member GetAvailableThreads Retrieves the difference between the maximum number of thread pool threads returned by the GetMaxThreads method, and the number currently active.
Public method Static member Supported by the XNA Framework Supported by Portable Class Library GetMaxThreads Retrieves the number of requests to the thread pool that can be active concurrently. All requests above that number remain queued until thread pool threads become available.
Public method Static member GetMinThreads Retrieves the minimum number of threads the thread pool creates on demand, as new requests are made, before switching to an algorithm for managing thread creation and destruction.
Public method Static member Supported by the XNA Framework Supported by Portable Class Library QueueUserWorkItem(WaitCallback) Queues a method for execution. The method executes when a thread pool thread becomes available.
Public method Static member Supported by the XNA Framework Supported by Portable Class Library QueueUserWorkItem(WaitCallback, Object) Queues a method for execution, and specifies an object containing data to be used by the method. The method executes when a thread pool thread becomes available.
Public method Static member RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean) Registers a delegate to wait for a WaitHandle, specifying a 32-bit signed integer for the time-out in milliseconds.
Public method Static member RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean) Registers a delegate to wait for a WaitHandle, specifying a 64-bit signed integer for the time-out in milliseconds.
Public method Static member RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean) Registers a delegate to wait for a WaitHandle, specifying a TimeSpan value for the time-out.
Public method Static member RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean) Registers a delegate to wait for a WaitHandle, specifying a 32-bit unsigned integer for the time-out in milliseconds.
Public method Static member Supported by the XNA Framework SetMaxThreads Sets the number of requests to the thread pool that can be active concurrently. All requests above that number remain queued until thread pool threads become available.
Public method Static member SetMinThreads Sets the minimum number of threads the thread pool creates on demand, as new requests are made, before switching to an algorithm for managing thread creation and destruction.
Public method Static member UnsafeQueueNativeOverlapped Queues an overlapped I/O operation for execution.
Public method Static member UnsafeQueueUserWorkItem Queues the specified delegate to the thread pool, but does not propagate the calling stack to the worker thread.
Public method Static member UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean) Registers a delegate to wait for a WaitHandle, using a 32-bit signed integer for the time-out in milliseconds. This method does not propagate the calling stack to the worker thread.
Public method Static member UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean) Registers a delegate to wait for a WaitHandle, specifying a 64-bit signed integer for the time-out in milliseconds. This method does not propagate the calling stack to the worker thread.
Public method Static member UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean) Registers a delegate to wait for a WaitHandle, specifying a TimeSpan value for the time-out. This method does not propagate the calling stack to the worker thread.
Public method Static member UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean) Registers a delegate to wait for a WaitHandle, specifying a 32-bit unsigned integer for the time-out in milliseconds. This method does not propagate the calling stack to the worker thread.
Top

Many applications create threads that spend a great deal of time in the sleeping state, waiting for an event to occur. Other threads might enter a sleeping state only to be awakened periodically to poll for a change or update status information. The thread pool enables you to use threads more efficiently by providing your application with a pool of worker threads that are managed by the system. Examples of operations that use thread pool threads include the following:

  • When you create a Task or Task(Of TResult) object to perform some task asynchronously, by default the task is scheduled to run on a thread pool thread.

  • Asynchronous timers use the thread pool. Thread pool threads execute callbacks from the System.Threading.Timer class and raise events from the System.Timers.Timer class.

  • When you use registered wait handles, a system thread monitors the status of the wait handles. When a wait operation completes, a worker thread from the thread pool executes the corresponding callback function.

Note 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.

You can also queue work items that are not related to a wait operation to the thread pool. To request that a work item be handled by a thread in the thread pool, call the QueueUserWorkItem method. This method takes as a parameter a reference to the method or delegate that will be called by the thread selected from the thread pool. There is no way to cancel a work item after it has been queued.

Timer-queue timers and registered wait operations also use the thread pool. Their callback functions are queued to the thread pool.

There is one thread pool per process. Beginning with the .NET Framework version 4, the default size of the thread pool for a process depends on several factors, such as the size of the virtual address space. A process can call the GetMaxThreads method to determine the number of threads. The number of threads in the thread pool can be changed by using the SetMaxThreads method. Each thread uses the default stack size and runs at the default priority.

Note Note

Unmanaged code that hosts the .NET Framework can change the size of the thread pool by using the CorSetMaxThreads function, defined in the mscoree.h file.

The thread pool provides new worker threads or I/O completion threads on demand until it reaches the minimum for each category. When a minimum is reached, the thread pool can create additional threads in that category or wait until some tasks complete. Beginning with the .NET Framework 4, the thread pool creates and destroys worker threads in order to optimize throughput, which is defined as the number of tasks that complete per unit of time. Too few threads might not make optimal use of available resources, whereas too many threads could increase resource contention.

Note Note

When demand is low, the actual number of thread pool threads can fall below the minimum values.

You can use the GetMinThreads method to obtain these minimum values.

Caution note Caution

You can use the SetMinThreads method to increase the minimum number of threads. However, unnecessarily increasing these values can cause performance problems. If too many tasks start at the same time, all of them might appear to be slow. In most cases the thread pool will perform better with its own algorithm for allocating threads.

When the thread pool reuses a thread, it does not clear the data in thread local storage or in fields that are marked with the ThreadStaticAttribute attribute. Therefore, data that is placed in thread local storage by one method can be exposed to any other method that is executed by the same thread pool thread. A method that accesses a field that is marked with the ThreadStaticAttribute attribute could encounter different data depending on which thread pool thread executes it.

Note Note

The HostProtectionAttribute attribute applied to this type or member has the following Resources property value: Synchronization | ExternalThreading. The HostProtectionAttribute does not affect desktop applications (which are typically started by double-clicking an icon, typing a command, or entering a URL in a browser). For more information, see the HostProtectionAttribute class or SQL Server Programming and Host Protection Attributes.

Topic Location
How to: Create an Asynchronous HTTP Handler Building ASP .NET Web Applications
How to: Create an Asynchronous HTTP Handler Building ASP .NET Web Applications

using System;
using System.Threading;
public class Example {
    public static void Main() {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));

        Console.WriteLine("Main thread does some work, then sleeps.");
        // If you comment out the Sleep, the main thread exits before
        // the thread pool task runs.  The thread pool uses background
        // threads, which do not keep the application running.  (This
        // is a simple example of a race condition.)
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object stateInfo) {
        // No state object was passed to QueueUserWorkItem, so 
        // stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}


.NET Framework

Supported in: 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

This type is thread safe.

Date

History

Reason

October 2010

Corrected outdated default size and outdated information about the creation of new threads.

Content bug fix.

Did you find this helpful?
(2000 characters remaining)
Community Content Add
Annotations FAQ
Default max threads
Note that ASP.net applications get their default max threads setting from ASP.net, not the CLR.  This may explain the inconsistencies noted in other comments.
default maximum thread pool member
default maximum thread pool member is 100 per CPU maybe right, i tested on virtual machine with ASP.NET 4.0, OS2008 R2 that has 4 virtual processor, default value i get is 400.
Available Threads
I have a single CPU, quad core system and I'm getting 1000 available threads (250 * cores) using the code in the comment above.
Outdated info for thread pool size

The article states that "There is one thread pool per process. The thread pool has a default size of 250 worker threads per available processor."

According to O'Reilly C# 4.0 in a Nutshell, this information is out of date. From page 805 of O"Reilly's reference:

You can set the upper limit of threads that the pool will create by calling Thread.Pool.SetMaxThreads, the defaults are

 

  • 1023 in 4.0 32 bit
  • 32768 in 4.0 64 bit
  • 250 per core in 3.5
  • 25 per core in 2.0

 

 


I hope this helps anyone who is confused. I don't know where O"Reilly gets this information, but it seems to be more accurate than the MSDN documentation. Happy coding!

ThreadPool.GetMaxThreads() shows only 100 per CPU
Edit: I give up trying to make this work. This feature is awful and keeps mangling my text and it adds in weird stuff. Oh well.

This article says that the max thread count should be 250 per CPU, but my tests as well as the tests by Steve Sanderson (Author of Pro ASP.NET MVC Framework 2) show that the max thread count is 100 per CPU.

The following code is what was used to get these numbers:
int wt;
int cpt;
ThreadPool.GetMaxThreads(out wt, out cpt);

Inspect the value of wt and you'll see that it is (100*CPUs). Are we missing something or is the documentation incorrect? If it is incorrect, this is a very large difference.