Пул управляемых потоковThe managed thread pool

Класс System.Threading.ThreadPool обеспечивает приложение пулом рабочих потоков, управляемых системой, позволяя пользователю сосредоточиться на выполнении задач приложения, а не на управлении потоками.The System.Threading.ThreadPool class provides your application with a pool of worker threads that are managed by the system, allowing you to concentrate on application tasks rather than thread management. Если имеются небольшие задачи, которые требуют фоновой обработки, пул управляемых потоков — это самый простой способ воспользоваться преимуществами нескольких потоков.If you have short tasks that require background processing, the managed thread pool is an easy way to take advantage of multiple threads. В Framework 4 и более поздних версиях использовать пул потоков стало значительно проще, так как вы можете создавать объекты Task и Task<TResult>, которые выполняют в потоках пула асинхронные задачи.Use of the thread pool is significantly easier in Framework 4 and later, since you can create Task and Task<TResult> objects that perform asynchronous tasks on thread pool threads.

Платформа .NET использует потоки из пула в различных целях, в том числе для операций библиотеки параллельных задач (TPL), асинхронного ввода-вывода, обратных вызовов таймера, регистрируемых операций ожидания, асинхронного вызова методов с использованием делегатов и для подключения к сокетам System.Net..NET uses thread pool threads for many purposes, including Task Parallel Library (TPL) operations, asynchronous I/O completion, timer callbacks, registered wait operations, asynchronous method calls using delegates, and System.Net socket connections.

Характеристики пула потоковThread pool characteristics

Потоки из пула являются фоновыми.Thread pool threads are background threads. Для каждого потока используется размер стека по умолчанию, поток запускается с приоритетом по умолчанию и находится в многопотоковом подразделении.Each thread uses the default stack size, runs at the default priority, and is in the multithreaded apartment. Когда поток в пуле завершает свою задачу, он возвращается в очередь потоков в состоянии ожидания.Once a thread in the thread pool completes its task, it's returned to a queue of waiting threads. С этого момента его можно использовать вновь.From this moment it can be reused. Повторное использование позволяет приложениям избежать дополнительных затрат на создание новых потоков для каждой задачи.This reuse enables applications to avoid the cost of creating a new thread for each task.

Для каждого процесса существует только один пул потоков.There is only one thread pool per process.

Исключения в потоках из пула потоковExceptions in thread pool threads

Необработанные исключения в потоках из пула приводят к завершению процесса.Unhandled exceptions in thread pool threads terminate the process. Существует три исключения из этого правила.There are three exceptions to this rule:

Дополнительные сведения см. в статье Исключения в управляемых потоках.For more information, see Exceptions in Managed Threads.

Максимальное число потоков в пуле потоковMaximum number of thread pool threads

Число операций, которое можно поставить в очередь в пуле потоков, ограничено только доступной памятью.The number of operations that can be queued to the thread pool is limited only by available memory. Однако пул потоков имеет ограничение на число потоков, которое можно активировать в процессе одновременно.However, the thread pool limits the number of threads that can be active in the process simultaneously. Если все потоки в пуле заняты, дополнительные рабочие элементы помещаются в очередь и ожидают их освобождения.If all thread pool threads are busy, additional work items are queued until threads to execute them become available. Начиная с .NET Framework 4, размер пула потоков по умолчанию для какого-либо процесса зависит от нескольких факторов, таких как размер виртуального адресного пространства.Beginning with the .NET Framework 4, the default size of the thread pool for a process depends on several factors, such as the size of the virtual address space. Процесс может вызвать метод ThreadPool.GetMaxThreads для определения количества потоков.A process can call the ThreadPool.GetMaxThreads method to determine the number of threads.

Вы можете управлять максимальным количеством потоков с помощью методов ThreadPool.GetMaxThreads и ThreadPool.SetMaxThreads.You can control the maximum number of threads by using the ThreadPool.GetMaxThreads and ThreadPool.SetMaxThreads methods.

Примечание

В коде, содержащем среду CLR, этот размер можно задать с помощью метода ICorThreadpool::CorSetMaxThreads.Code that hosts the common language runtime can set the size using the ICorThreadpool::CorSetMaxThreads method.

Минимальные значения пула потоковThread pool minimums

Пул потоков предоставляет новые рабочие потоки или потоки завершения ввода-вывода по запросу, пока не будет достигнут заданный минимум для каждой категории.The thread pool provides new worker threads or I/O completion threads on demand until it reaches a specified minimum for each category. Для получения этих минимальных значений можно использовать метод ThreadPool.GetMinThreads.You can use the ThreadPool.GetMinThreads method to obtain these minimum values.

Примечание

Если потребность низкая, фактическое количество потоков из пула потоков может быть ниже минимальных значений.When demand is low, the actual number of thread pool threads can fall below the minimum values.

При достижении минимума пул потоков может создавать дополнительные потоки или ожидать завершения некоторых задач.When a minimum is reached, the thread pool can create additional threads or wait until some tasks complete. Начиная с .NET Framework 4, пул потоков создает и уничтожает рабочие потоки в целях оптимизации пропускной способности, которая определяется как количество задач, выполняемых в единицу времени.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.

Внимание!

Для увеличения минимального количества бездействующих потоков можно использовать метод ThreadPool.SetMinThreads.You can use the ThreadPool.SetMinThreads method to increase the minimum number of idle 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.

Использование пула потоковUsing the thread pool

Начиная с .NET Framework 4, самым простым способом использования пула потоков является применение библиотеки параллельных задач (TPL).Beginning with the .NET Framework 4, the easiest way to use the thread pool is to use the Task Parallel Library (TPL). По умолчанию такие типы TPL, как Task и Task<TResult>, используют потоки из пула для выполнения задач.By default, TPL types like Task and Task<TResult> use thread pool threads to run tasks.

Пул потоков также можно использовать путем вызова ThreadPool.QueueUserWorkItem из управляемого кода (или ICorThreadpool::CorQueueUserWorkItem из неуправляемого кода) и передачи делегата System.Threading.WaitCallback, представляющего метод, который выполняет задачу.You can also use the thread pool by calling ThreadPool.QueueUserWorkItem from managed code (or ICorThreadpool::CorQueueUserWorkItem from unmanaged code) and passing a System.Threading.WaitCallback delegate representing the method that performs the task.

Другим способом использования пула потоков является помещение в очередь рабочих элементов, которые имеют отношение к операции ожидания, с помощью метода ThreadPool.RegisterWaitForSingleObject и передача дескриптора System.Threading.WaitHandle, который вызывает метод, представленный делегатом System.Threading.WaitOrTimerCallback, при получении сигнала или истечении времени ожидания.Another way to use the thread pool is to queue work items that are related to a wait operation by using the ThreadPool.RegisterWaitForSingleObject method and passing a System.Threading.WaitHandle that, when signaled or when timed out, calls the method represented by the System.Threading.WaitOrTimerCallback delegate. Потоки из пула потоков используются для вызова методов обратного вызова.Thread pool threads are used to invoke callback methods.

Примеры см. по ссылкам на страницы API.For the examples, check the referenced API pages.

Пропуск проверок безопасностиSkipping security checks

Пул потоков также предоставляет методы ThreadPool.UnsafeQueueUserWorkItem и ThreadPool.UnsafeRegisterWaitForSingleObject.The thread pool also provides the ThreadPool.UnsafeQueueUserWorkItem and ThreadPool.UnsafeRegisterWaitForSingleObject methods. Используйте эти методы только в том случае, если вы уверены, что стек вызывающего объекта не важен для проверок безопасности, осуществляемых во время выполнения задачи в очереди.Use these methods only when you are certain that the caller's stack is irrelevant to any security checks performed during the execution of the queued task. ThreadPool.QueueUserWorkItem и ThreadPool.RegisterWaitForSingleObject перехватывают стек вызывающего объекта, который объединяется со стеком потока из пула потоков, когда поток начинает выполнять задачу.ThreadPool.QueueUserWorkItem and ThreadPool.RegisterWaitForSingleObject both capture the caller's stack, which is merged into the stack of the thread pool thread when the thread begins to execute a task. Если требуется проверка безопасности, проверяется весь стек.If a security check is required, the entire stack must be checked. Несмотря на обеспечение безопасности, такая проверка также влияет на производительность.Although the check provides safety, it also has a performance cost.

Когда не следует использовать потоки из пула потоковWhen not to use thread pool threads

Существует ряд сценариев, в которых следует создавать собственные потоки и работать с ними, а не использовать потоки из пула:There are several scenarios in which it's appropriate to create and manage your own threads instead of using thread pool threads:

  • Необходим основной поток.You require a foreground thread.
  • Поток должен иметь определенный приоритет.You require a thread to have a particular priority.
  • Имеются задачи, которые приводят к блокировке потока на длительное время.You have tasks that cause the thread to block for long periods of time. Для пула потоков определено максимальное количество потоков, поэтому большое число заблокированных потоков в пуле может препятствовать запуску задач.The thread pool has a maximum number of threads, so a large number of blocked thread pool threads might prevent tasks from starting.
  • Необходимо поместить потоки в однопотоковое подразделение.You need to place threads into a single-threaded apartment. Все потоки ThreadPool находятся в многопотоковом подразделении.All ThreadPool threads are in the multithreaded apartment.
  • Необходимо иметь постоянное удостоверение, сопоставленное с потоком, или назначить поток задаче.You need to have a stable identity associated with the thread, or to dedicate a thread to a task.

См. такжеSee also