Pregunta

Aquí hay una tarea relativamente común para mí y, creo, para muchos programadores .NET:
Quiero usar .NET ThreadPool para programar hilos de trabajo que necesiten procesar un tipo dado de tareas.

Como recordatorio, las firmas para el método de cola del ThreadPool y su delegado asociado son:

public static bool QueueUserWorkItem (
    WaitCallback callBack,
    Object state
)
public delegate void WaitCallback (Object state)

Por lo tanto, una clase de subproceso de trabajo genérica típica se vería así:

public class Worker<T> {
    public void schedule(T i_task) {
        ThreadPool.QueueUserWorkItem(execute, i_task)
    }
    private void execute(Object o){
        T task = (T)o;  //What happened to the type safety?  
        executeTask(task);
    }
    private void executeTask(T i_task){
        //process i_task
    }
}

¿Observe el tipo del parámetro state ? Es Object !

¿Cuál es la razón convincente por la cual el equipo .NET decidió no hacer que el método QueueUserWorkItem (o toda la clase ThreadPool ) sea genérico? No puedo creer que lo hayan pasado por alto.

Así es como me gustaría verlo:

//in the ThreadPool class:
public static bool QueueUserWorkItem<T> (
    WaitCallback<T> callBack,
    T state
)
public delegate void WaitCallback<T> (T state)

Esto haría que la clase trabajadora sea segura (y mucho más clara, en mi humilde opinión):

public class Worker<T> {
    public void schedule(T i_task) {
        ThreadPool.QueueUserWorkItem<T>(execute, i_task)
    }
    private void execute(T i_task){
        //process i_task
    }
}

Debo estar perdiendo algo.

¿Fue útil?

Solución

¿Parece que estás hablando de una cola de trabajo? (y sueno como clippy ...)

Para el registro, los subprocesos de grupo de subprocesos generalmente se deben usar para trabajos cortos. Idealmente, debe crear sus propios hilos para una cola de larga duración. Tenga en cuenta que .NET 4.0 puede estar adoptando las bibliotecas CCR / TPL, por lo que obtendremos algunas colas de trabajo incorporadas de forma gratuita, pero no es difícil escribir una cola de trabajo con hilos. Y también puede hacerlo genérico ;-p

Re la pregunta: prefiero el enfoque de las variables capturadas para pasar el estado a hilos (ya sea Thread , ThreadPool o Control.Invoke ):

    Thread t = new Thread(() => SomeMethod(arg));
    t.IsBackground = true;
    t.Name = "Worker n";
    t.Start();

Esto le brinda un control mucho más granular sobre el hilo, sin saturar el ThreadPool .

Otros consejos

Dado que es trivial empaquetar el estado que desee al pasar un delegado anónimo o lambda al conjunto de subprocesos (a través de la captura variable), no hay necesidad de una versión genérica.

Por ejemplo, podría escribir una función de utilidad:

static void QueueItem<T>(Action<T> action, T state)
{
    ThreadPool.QueueUserWorkItem(delegate { action(state); });
}

Pero no sería terriblemente útil, ya que simplemente puede usar un delegado usted mismo cada vez que necesite un estado en la tarea agrupada.

ThreadPool existe desde .NET 1.1 que no tenía genéricos.

Me gusta cómo decidieron no romper la compatibilidad con versiones anteriores :-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top