2011-12-19 780 views
7

Después de haber leído la documentación de la clase Dispatcher, me doy cuenta de que también se puede usar para la cola de acciones que no son de la interfaz de usuario.Dispatcher - ¿Cómo funciona?

Entonces, ¿cómo funciona realmente la clase Dispatcher? Soy consciente de eso, su trabajo principal es poner en cola las acciones a un hilo específico, pero ¿cómo "envía" esas acciones al hilo? ¿Y cómo el hilo "obtiene" estas acciones?

Mi mejor versión es que hay algún tipo de "cola de hilos" para cada hilo, pero una vez más no tengo ni idea.

+0

¿Está preguntando en el contexto de WPF o Silverlight? –

+0

@JoeWhite, Ninguno. También puedes usar el 'Dispatcher' en una aplicación que no es gui. – ebb

+2

@ebb, puedes usarlo en una aplicación sin GUI, pero realmente no tiene sentido ... hay herramientas más adecuadas para hacerlo. El despachador * está * diseñado teniendo en cuenta los escenarios de IU. –

Respuesta

2

No es una tarea trivial obtener un hilo para iniciar la ejecución del código en otro hilo. La clave del problema es que no se puede simplemente decir cualquier hilo para comenzar a ejecutar un método después de que ese hilo ya haya comenzado. El hilo de destino debe configurarse específicamente para recibir este tipo de solicitudes con anticipación.

El patrón habitual utilizado es el productor-consumidor. El hilo de destino girará alrededor de un bucle infinito esperando que los mensajes aparezcan en una cola de bloqueo. La cola está diseñada para bloquear hasta que aparezca un elemento en la cola, lo que evita que el hilo de destino consuma tiempo de CPU innecesariamente. Aquí hay una manera muy simple de obtener un hilo para aceptar la inyección de un delegado para su ejecución.

public class Example 
{ 
    private BlockingCollection<Action> queue = new BlockingCollection<Action>(); 

    public Example() 
    { 
    new Thread(
    () => 
     { 
     while (true) 
     { 
      Action action = queue.Take(); 
      action(); 
     } 
     }).Start(); 
    } 

    public void ExecuteAsync(Action action) 
    { 
    queue.Add(action); 
    } 
} 

Ahora, en el caso de una interfaz de usuario hilo que ya tiene un bucle de mensaje se ejecuta por lo que la clase Dispatcher puede simplemente enviar un mensaje especial para la cola de mensajes que contiene el delegado para ser ejecutado. En el medio de procesar toda la pintura, los clics de los botones, etc., este mensaje especial también será recogido por el subproceso de la interfaz de usuario y comenzará a ejecutarse el delegado.

Entonces, ¿cómo funciona realmente la clase Dispatcher? Soy consciente de eso, , su trabajo principal es poner en cola acciones en un hilo específico, pero ¿cómo "envía" esas acciones al hilo ?

Al poner en cola a un delegado en una cola que supervisa el subproceso de destino.

¿Y cómo el hilo "obtiene" estas acciones?

Ejecutando un bucle infinito que supervisa la cola. La cola suele ser un tipo especial llamado cola de bloqueo que bloquea el hilo consumidor si la cola está vacía.

Mi mejor versión es que hay algún tipo de "lista de hilos" para cada hilo , pero de nuevo no tengo ni idea.

Pretty close. Excepto que los hilos no tienen una cola incorporada para este propósito. Tiene que ser configurado manualmente. Es por eso que solo los hilos diseñados específicamente pueden aceptar inyecciones de delegado. Los subprocesos de interfaz de usuario se configuran de esta manera porque Application.Run crea el bucle de mensaje. En mi ejemplo, verá que tuve que usar BlockingCollection y un bucle infinito para que funcione en un hilo de trabajo.

+0

¡Gracias por la respuesta! - Entiendo completamente el concepto productor/consumidor, etc. Lo que estoy cuestionando es cómo/por qué el 'Dispatcher' también funciona en una aplicación que no es de GUI. En este momento estoy mirando el código fuente de la clase real 'Dispatcher', y parece que crea una" ventana de solo mensaje ", y por lo tanto también un ciclo de mensajes, pero de nuevo ... No estoy seguro del todo . – ebb

0

pregunta muy interesante, pero no es necesario una ventana para tener una cola de mensajes, estos son conceptos distintos, puede crear una cola de mensajes sobre cualquier tema con sólo llamar PeekMessage.

For more information take a look at here

pero por supuesto esto no significa que un despachador sin una ventana es de ninguna utilidad. Puedo suponer que los diseñadores estaban pensando en un objeto Dispatcher independiente para permitir que maneje tantas ventanas como tenga la aplicación.

Cuestiones relacionadas