ThreadPool Clase

Definición

Proporciona un grupo de subprocesos que pueden usarse para ejecutar tareas, exponer elementos de trabajo, procesar la E/S asincrónica, esperar en nombre de otros subprocesos y procesar temporizadores.

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
Herencia
ThreadPool

Ejemplos

En el ejemplo siguiente, el subproceso de aplicación principal pone en cola un método denominado ThreadProc para ejecutarse en un subproceso del grupo de subprocesos, se suspende durante un segundo y, a continuación, se cierra. El ThreadProc método simplemente muestra un mensaje.

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.

Si comenta la llamada al Thread.Sleep método , el subproceso principal sale antes de que el método se ejecute en el subproceso del grupo de subprocesos. El grupo de subprocesos usa subprocesos en segundo plano, que no mantienen la aplicación en ejecución si todos los subprocesos en primer plano han finalizado. (Este es un ejemplo sencillo de una condición de carrera).

Comentarios

Muchas aplicaciones crean subprocesos que pasan mucho tiempo en estado de suspensión, esperando a que se produzca un evento. Otros subprocesos pueden entrar en un estado de suspensión solo para despertarse periódicamente para sondear una información de estado de cambio o actualización. El grupo de subprocesos permite usar subprocesos de forma más eficaz proporcionando a la aplicación un grupo de subprocesos de trabajo administrados por el sistema. Entre los ejemplos de operaciones que usan subprocesos del grupo de subprocesos se incluyen los siguientes:

  • Cuando se crea un Task objeto o Task<TResult> para realizar alguna tarea de forma asincrónica, de forma predeterminada, la tarea está programada para ejecutarse en un subproceso del grupo de subprocesos.

  • Los temporizadores asincrónicos usan el grupo de subprocesos. Los subprocesos del grupo de subprocesos ejecutan devoluciones de llamada desde la System.Threading.Timer clase y generan eventos de la System.Timers.Timer clase .

  • Cuando se usan identificadores de espera registrados, un subproceso del sistema supervisa el estado de los identificadores de espera. Cuando se completa una operación de espera, un subproceso de trabajo del grupo de subprocesos ejecuta la función de devolución de llamada correspondiente.

  • Cuando se llama al QueueUserWorkItem método para poner en cola un método para su ejecución en un subproceso de grupo de subprocesos. Para ello, pase el método un WaitCallback delegado. El delegado tiene la firma

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

    donde state es un objeto que contiene los datos que va a usar el delegado. Los datos reales se pueden pasar al delegado llamando al QueueUserWorkItem(WaitCallback, Object) método .

Nota

Los subprocesos del grupo de subprocesos administrados son subprocesos en segundo plano. Es decir, sus IsBackground propiedades son true. Esto significa que un ThreadPool subproceso no mantendrá una aplicación en ejecución después de que se hayan salido todos los subprocesos en primer plano.

Importante

Cuando el grupo de subprocesos reutiliza un subproceso, no borra los datos en el almacenamiento local del subproceso ni en campos marcados con el ThreadStaticAttribute atributo . Por lo tanto, cuando un método examina el almacenamiento local del subproceso o los campos marcados con el ThreadStaticAttribute atributo , los valores que encuentra podrían dejarse de un uso anterior del subproceso del grupo de subprocesos.

También puede poner en cola los elementos de trabajo que no están relacionados con una operación de espera al grupo de subprocesos. Para solicitar que un subproceso del grupo de subprocesos controle un elemento de trabajo, llame al QueueUserWorkItem método . Este método toma como parámetro una referencia al método o delegado al que llamará el subproceso seleccionado en el grupo de subprocesos. No hay ninguna manera de cancelar un elemento de trabajo después de que se haya puesto en cola.

Los temporizadores de cola de temporizador y las operaciones de espera registradas también usan el grupo de subprocesos. Sus funciones de devolución de llamada se ponen en cola en el grupo de subprocesos.

Hay un grupo de subprocesos por proceso. A partir de .NET Framework 4, el tamaño predeterminado del grupo de subprocesos de un proceso depende de varios factores, como el tamaño del espacio de direcciones virtuales. Un proceso puede llamar al método GetMaxThreads para determinar el número de subprocesos. El número de subprocesos del grupo de subprocesos se puede cambiar mediante el SetMaxThreads método . Cada subproceso usa el tamaño de pila predeterminado y se ejecuta con la prioridad predeterminada.

Nota

El código no administrado que hospeda .NET Framework puede cambiar el tamaño del grupo de subprocesos mediante la CorSetMaxThreads función , definida en el archivo mscoree.h.

El grupo de subprocesos proporciona nuevos subprocesos de trabajo o subprocesos de finalización de E/S a petición hasta que alcanza el máximo para cada categoría. Cuando se alcanza un máximo, el grupo de subprocesos puede crear subprocesos adicionales en esa categoría o esperar hasta que se completen algunas tareas. A partir de .NET Framework 4, el grupo de subprocesos crea y destruye subprocesos de trabajo para optimizar el rendimiento, definido como el número de tareas que se completan por unidad de tiempo. Si hay demasiados pocos subprocesos, puede que los recursos disponibles no se usen de manera óptima, mientras que si hay demasiados subprocesos, puede aumentar la contención de recursos.

Nota

Cuando la demanda es baja, el número real de subprocesos del grupo de subprocesos puede descender por debajo de los valores mínimos.

Puede utilizar el método GetMinThreads para obtener estos valores mínimos.

Precaución

Puede usar el SetMinThreads método para aumentar el número mínimo de subprocesos. Sin embargo, aumentar innecesariamente estos valores puede causar problemas de rendimiento. Si se inician demasiadas tareas al mismo tiempo, puede que todas ellas parezcan funcionar con lentitud. En la mayoría de los casos, el grupo de subprocesos funciona mejor con su propio algoritmo de asignación de subprocesos.

Propiedades

CompletedWorkItemCount

Obtiene el número de elementos de trabajo que se han procesado hasta ahora.

PendingWorkItemCount

Obtiene el número de elementos de trabajo que se encuentran actualmente en cola para procesarse.

ThreadCount

Obtiene el número de subprocesos del grupo de subprocesos que existen actualmente.

Métodos

BindHandle(IntPtr)
Obsoleto.
Obsoleto.

Enlaza un identificador del sistema operativo a ThreadPool.

BindHandle(SafeHandle)

Enlaza un identificador del sistema operativo a ThreadPool.

GetAvailableThreads(Int32, Int32)

Recupera la diferencia entre el número máximo de subprocesos de grupo de subprocesos devuelto por el método GetMaxThreads(Int32, Int32) y el número activo actualmente.

GetMaxThreads(Int32, Int32)

Recupera el número de solicitudes al grupo de subprocesos que pueden estar activas al mismo tiempo. Todas las solicitudes que pasen de ese número permanecen en la cola hasta que haya disponibles subprocesos de grupo de subprocesos.

GetMinThreads(Int32, Int32)

Recupera el número mínimo de subprocesos que el grupo de subprocesos crea a petición, según se realizan nuevas solicitudes, antes de conmutar a un algoritmo para administrar la creación y destrucción de subprocesos.

QueueUserWorkItem(WaitCallback)

Pone en cola un método para su ejecución. El método se ejecuta cuando hay disponible un subproceso de grupo de subprocesos.

QueueUserWorkItem(WaitCallback, Object)

Pone un método en cola para su ejecución y especifica un objeto que contiene los datos que debe usar el método. El método se ejecuta cuando hay disponible un subproceso de grupo de subprocesos.

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

Pone un método en cola para su ejecución especificado por un delegado de Action<T> y proporciona los datos que debe usar el método. El método se ejecuta cuando hay disponible un subproceso de grupo de subprocesos.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un entero de 32 bits con signo como tiempo de espera, en milisegundos.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un entero de 64 bits con signo como tiempo de espera, en milisegundos.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un valor TimeSpan como tiempo de espera.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un entero de 32 bits sin signo como tiempo de espera, en milisegundos.

SetMaxThreads(Int32, Int32)

Establece el número de solicitudes al grupo de subprocesos que pueden estar activas al mismo tiempo. Todas las solicitudes que pasen de ese número permanecen en la cola hasta que haya disponibles subprocesos de grupo de subprocesos.

SetMinThreads(Int32, Int32)

Establece el número mínimo de subprocesos que el grupo de subprocesos crea a petición, según se realizan nuevas solicitudes, antes de conmutar a un algoritmo para administrar la creación y destrucción de subprocesos.

UnsafeQueueNativeOverlapped(NativeOverlapped*)

Pone en cola una operación de E/S superpuesta para que se ejecute.

UnsafeQueueUserWorkItem(IThreadPoolWorkItem, Boolean)

Pone en cola el objeto del elemento de trabajo especificado en el grupo de subprocesos.

UnsafeQueueUserWorkItem(WaitCallback, Object)

Pone en cola el delegado especificado en el grupo de subprocesos, pero no propaga la pila de llamadas al subproceso de trabajo.

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

Pone un método en cola para su ejecución especificado por un delegado de Action<T> y especifica un objeto que contiene los datos que debe usar el método. El método se ejecuta cuando hay disponible un subproceso de grupo de subprocesos.

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

Registra un delegado para que espere a la clase WaitHandle y usa un entero de 32 bits con signo como tiempo de espera, en milisegundos. Este método no propaga la pila de llamadas al subproceso de trabajo.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un entero de 64 bits con signo como tiempo de espera, en milisegundos. Este método no propaga la pila de llamadas al subproceso de trabajo.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un valor TimeSpan como tiempo de espera. Este método no propaga la pila de llamadas al subproceso de trabajo.

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

Registra un delegado para que espere a la clase WaitHandle y especifica un entero de 32 bits sin signo como tiempo de espera, en milisegundos. Este método no propaga la pila de llamadas al subproceso de trabajo.

Se aplica a

Seguridad para subprocesos

Este tipo es seguro para la ejecución de subprocesos.

Consulte también