ThreadPool Класс

Определение

Предоставляет пул потоков, который можно использовать для выполнения задач, отправки рабочих элементов, обработки асинхронного ввода-вывода, ожидания от имени других потоков и обработки таймеров.

public ref class ThreadPool abstract sealed
public ref class ThreadPool sealed
public static class ThreadPool
public sealed class ThreadPool
type ThreadPool = class
Public Class ThreadPool
Public NotInheritable Class ThreadPool
Наследование
ThreadPool

Примеры

В следующем примере основной поток приложения помещает в очередь метод с именем ThreadProc для выполнения в потоке пула потоков, переходит в спящий режим на одну секунду, а затем завершает работу. Метод ThreadProc просто отображает сообщение.

using namespace System;
using namespace System::Threading;

ref class Example
{
public:

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

int main()
{
   // Queue the task.
   ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc));

   Console::WriteLine("Main thread does some work, then sleeps.");
   
   Thread::Sleep(1000);
   Console::WriteLine("Main thread exits.");
   return 0;
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
using System;
using System.Threading;

public class Example 
{
    public static void Main() 
    {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(ThreadProc);
        Console.WriteLine("Main thread does some work, then sleeps.");
        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.");
    }
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
Imports System.Threading

Public Module Example
    Public Sub Main()
        ' Queue the work for execution.
        ThreadPool.QueueUserWorkItem(AddressOf ThreadProc)
        
        Console.WriteLine("Main thread does some work, then sleeps.")

        Thread.Sleep(1000)

        Console.WriteLine("Main thread exits.")
    End Sub

    ' This thread procedure performs the task.
    Sub ThreadProc(stateInfo As Object)
        ' No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.")
    End Sub
End Module
' The example displays output like the following:
'       Main thread does some work, then sleeps.
'       Hello from the thread pool.
'       Main thread exits.

Если закомментировать вызов Thread.Sleep метода, основной поток завершает работу перед выполнением метода в потоке пула потоков. Пул потоков использует фоновые потоки, которые не сохраняют работу приложения, если все потоки переднего плана завершены. (Это простой пример состояния гонки.)

Комментарии

Многие приложения создают потоки, которые проводят много времени в спящем состоянии, ожидая возникновения события. Другие потоки могут переходить в спящее состояние только для периодического пробуждения для опроса сведений об изменении или обновлении сведений о состоянии. Пул потоков позволяет более эффективно использовать потоки, предоставляя приложению пул рабочих потоков, управляемых системой. Ниже приведены примеры операций, использующих потоки пула потоков.

  • При создании Task объекта или Task<TResult> для асинхронного выполнения некоторых задач задача по умолчанию планируется для выполнения в потоке пула потоков.

  • Асинхронные таймеры используют пул потоков. Потоки пула потоков выполняют обратные System.Threading.Timer вызовы из класса и вызывают события из System.Timers.Timer класса .

  • При использовании зарегистрированных дескрипторов ожидания системный поток отслеживает состояние дескрипторов ожидания. После завершения операции ожидания рабочий поток из пула потоков выполняет соответствующую функцию обратного вызова.

  • При вызове метода для постановки QueueUserWorkItem метода в очередь для выполнения в потоке пула потоков. Для этого метод передается делегату WaitCallback . Делегат имеет сигнатуру

    void WaitCallback(Object state)
    
    Sub WaitCallback(state As Object)
    

    где state — это объект, содержащий данные, используемые делегатом. Фактические данные можно передать делегату, вызвав QueueUserWorkItem(WaitCallback, Object) метод .

Примечание

Потоки в пуле управляемых потоков являются фоновыми потоками. То есть их IsBackground свойства имеют значение true. Это означает, что ThreadPool поток не будет поддерживать работу приложения после выхода всех потоков переднего плана.

Важно!

Когда пул потоков повторно использует поток, он не очищает данные в локальном хранилище потока или в полях, помеченных атрибутом ThreadStaticAttribute . Таким образом, когда метод проверяет локальное хранилище потока или поля, помеченные атрибутом ThreadStaticAttribute , полученные значения могут остаться после более раннего использования потока пула потоков.

Вы также можете помещать в очередь рабочие элементы, не связанные с операцией ожидания, в пул потоков. Чтобы запросить обработку рабочего элемента потоком в пуле потоков, вызовите QueueUserWorkItem метод . Этот метод принимает в качестве параметра ссылку на метод или делегат, который будет вызываться потоком, выбранным из пула потоков. Отменить рабочий элемент после его постановки в очередь невозможно.

Таймеры очереди таймеров и зарегистрированные операции ожидания также используют пул потоков. Их функции обратного вызова помещаются в очередь в пул потоков.

Для каждого процесса существует один пул потоков. Начиная с .NET Framework 4, размер пула потоков по умолчанию для какого-либо процесса зависит от нескольких факторов, таких как размер виртуального адресного пространства. Процесс может вызвать метод GetMaxThreads для определения количества потоков. Количество потоков в пуле потоков можно изменить с помощью SetMaxThreads метода . Каждый поток использует размер стека по умолчанию и выполняется с приоритетом по умолчанию.

Примечание

Неуправляемый код, в котором размещается платформа .NET Framework, может изменить размер пула потоков с помощью CorSetMaxThreads функции, определенной в файле mscoree.h.

Пул потоков предоставляет новые рабочие потоки или потоки завершения ввода-вывода по запросу, пока не достигнет максимального значения для каждой категории. При достижении максимального значения пул потоков может создавать дополнительные потоки в этой категории или ждать завершения некоторых задач. Начиная с .NET Framework 4, пул потоков создает и уничтожает рабочие потоки в целях оптимизации пропускной способности, которая определяется как количество задач, выполняемых в единицу времени. Слишком малое количество потоков может препятствовать оптимальному использованию доступных ресурсов, тогда как слишком большое их количество может усиливать конкуренцию за ресурсы.

Примечание

Если потребность низкая, фактическое количество потоков из пула потоков может быть ниже минимальных значений.

Для получения этих минимальных значений можно использовать метод GetMinThreads.

Внимание!

Метод можно использовать для SetMinThreads увеличения минимального количества потоков. Однако необоснованное увеличение этих значений может привести к снижению производительности. Если одновременно запускается слишком много задач, все они могут выполняться слишком медленно. В большинстве случаев пул потоков работает наилучшим образом, если он использует собственный алгоритм выделения потоков.

Свойства

CompletedWorkItemCount

Возвращает количество рабочих элементов, обработанных на данный момент.

PendingWorkItemCount

Возвращает количество рабочих элементов, находящихся в настоящее время в очереди на обработку.

ThreadCount

Возвращает текущее количество потоков в пуле потоков.

Методы

BindHandle(IntPtr)
Устаревшие..
Устаревшие..

Связывает дескриптор операционной системы с объектом ThreadPool.

BindHandle(SafeHandle)

Связывает дескриптор операционной системы с объектом ThreadPool.

GetAvailableThreads(Int32, Int32)

Возвращает разницу между максимальным числом потоков пула, возвращаемых методом GetMaxThreads(Int32, Int32), и числом активных в данный момент потоков.

GetMaxThreads(Int32, Int32)

Возвращает количество запросов к пулу потоков, которые могут быть активными одновременно. Все запросы, превышающие это количество, остаются в очереди до тех пор, пока потоки пула не станут доступны.

GetMinThreads(Int32, Int32)

Возвращает минимальное число потоков, создаваемых пулом потоков по требованию по мере поступления новых запросов перед переходом на алгоритм управления созданием и уничтожением потоков.

QueueUserWorkItem(WaitCallback)

Помещает метод в очередь на выполнение. Метод выполняется, когда становится доступен поток из пула потоков.

QueueUserWorkItem(WaitCallback, Object)

Помещает метод в очередь на выполнение и указывает объект, содержащий данные для использования методом. Метод выполняется, когда становится доступен поток из пула потоков.

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Помещает метод, определенный делегатом Action<T>, в очередь на выполнение и указывает данные для этого метода. Метод выполняется, когда становится доступен поток из пула потоков.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая время ожидания в миллисекундах в виде 32-разрядного целого числа со знаком.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая время ожидания в миллисекундах в виде 64-разрядного целого числа со знаком.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая значение TimeSpan для времени ожидания.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая время ожидания в миллисекундах в виде 32-разрядного целого числа без знака.

SetMaxThreads(Int32, Int32)

Задает количество запросов к пулу потоков, которые могут быть активными одновременно. Все запросы, превышающие это количество, остаются в очереди до тех пор, пока потоки пула не станут доступны.

SetMinThreads(Int32, Int32)

Задает минимальное число потоков, создаваемых пулом потоков по требованию по мере поступления новых запросов перед переходом на алгоритм управления созданием и уничтожением потоков.

UnsafeQueueNativeOverlapped(NativeOverlapped*)

Помещает в очередь на выполнение операцию перекрывающегося ввода-вывода.

UnsafeQueueUserWorkItem(IThreadPoolWorkItem, Boolean)

Помещает указанный объект рабочего элемента в очередь в пул потоков.

UnsafeQueueUserWorkItem(WaitCallback, Object)

Помещает указанный делегат в очередь пула потоков, но не распространяет вызывающий стек на рабочий поток.

UnsafeQueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Помещает метод, определенный делегатом Action<T>, в очередь на выполнение и указывает объект, содержащий данные для этого метода. Метод выполняется, когда становится доступен поток из пула потоков.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая время ожидания в миллисекундах в виде 32-разрядного целого числа со знаком. Этот метод не распространяет вызывающий стек на рабочий поток.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая время ожидания в миллисекундах в виде 64-разрядного целого числа со знаком. Этот метод не распространяет вызывающий стек на рабочий поток.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая значение TimeSpan для времени ожидания. Этот метод не распространяет вызывающий стек на рабочий поток.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Регистрирует делегат для ожидания объекта WaitHandle, задавая время ожидания в миллисекундах в виде 32-разрядного целого числа без знака. Этот метод не распространяет вызывающий стек на рабочий поток.

Применяется к

Потокобезопасность

Данный тип потокобезопасен.

См. также раздел