2012-07-10 21 views
14

Creo que necesito ayuda para entender el Cola del despachador.Entender la cola del despachador

Cuando llega un nuevo trabajo, se agrega al principio de la cola del despachador y cuando el despachador desea procesar un elemento que funciona, se elimina desde el principio.

En términos más generales: si hay trabajo, se almacena de manera FIFO dentro de la cola y se procesa mientras no quede trabajo.

La documentación de MSDN here se refiere a un loop y una frame:

The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.

Pero dónde está un bucle en este contexto? Para mí, un ciclo es algo que itera sobre algo y cuando llega al final comienza de nuevo.

¿Y cuál es el concepto de frame? Según la documentación de MSDN, ¿un marco es un puñado de elementos de trabajo dentro de la cola? Si eso es cierto, ¿cómo debe usarse el método estático Disptatcher.PushFrame()?

Y la pregunta más interesante es si hay alguna forma de obtener el estado actual de la cola, especialmente cuántos elementos hay en la cola.

¿Se mantiene si un método que se ha invocado antes (y por lo tanto puesto en la cola Dispatcher) se ejecuta que luego se elimina de la cola inmediatamente o dura por dentro por otro período de tiempo?

lo sé, Tantas preguntas :-)

+1

Primera pregunta: ¿por qué? ¿Por qué quieres hacer algo con Dispatcher? Normalmente, Dispatcher es simplemente la "bomba de mensajes" para un proceso de WPF. Maneja todos los mensajes/eventos/comandos a través de la interfaz de usuario de WPF al código de la aplicación (por ejemplo, movimiento del mouse, clics, etc.) Cuando se invoca el método Run de las aplicaciones, llama a PushFrame para iniciar ese ciclo. No puede iniciar otro para el mismo hilo; y Dispatcher está destinado a procesar el trabajo de UI. –

+2

¿Has leído sobre el [modelo de subprocesamiento] (http://msdn.microsoft.com/en-us/library/ms741870.aspx)? –

+1

Es una solución estándar para el problema productor-consumidor: http://en.wikipedia.org/wiki/Producer-consumer_problem –

Respuesta

22

hay muy poca documentación que rodea el Dispatcher, por lo que tendrá que desmontar un poco para saber sobre el funcionamiento interno.

Un despachador es básicamente algo que funciona alrededor de la aplicación Message Pump. El que está en cuestión se encuentra en la parte superior de windows message loop.

Como consecuencia, solo puede haber una aplicación Dispatcher: el objeto de despachador global al que se puede acceder mediante Application.Current.Dispatcher. Otros despachadores son posibles mediante el acceso a Dispatcher.CurrentDispatcher, que según la documentación

Obtiene el despachador para el subproceso en ejecución actualmente y crea una nueva Dispatcher si uno no esté asociada con el hilo.

Sin embargo, llamar al Run en este nuevo despachador será un bloqueo.

Cuando hace un Dispatcher.PushFrame, básicamente empuja un marco en el despachador actual. Todo lo que hereda de DispatcherObject como DispatcherFrame tendrá su despachador configurado al actual. Podemos verificar esto mirando su constructor.

private Dispatcher _dispatcher; 

protected DispatcherObject() 
{ 
    this._dispatcher = Dispatcher.CurrentDispatcher; 
} 

Por supuesto, tener un bucle de eventos simple no es suficiente - hay momentos en que necesita para subvertir el bucle de eventos actual para forzar otro trabajo por hacer. Y es por eso que tiene un DispatcherFrame.Esto es lo que realmente constituye el ciclo de eventos. Cuando se presiona un marco en el Dispatcher, esto es lo que sucede:

while (frame.Continue) 
     { 
      if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0)) 
      { 
       break; 
      } 
      this.TranslateAndDispatchMessage(ref msg); 
     } 

Es en el TranslateAndDispatchMessage que la cola de prioridad en el despachador se evalúa, después de un mensaje se saca.

Si una operación tarda mucho tiempo en ejecutarse en el despachador, detiene temporalmente el bucle de evento y porque no responde a la señalización, parece que la aplicación deja de responder.

Here's an article que usa un marco para forzar a la IU a responder permitiendo que el bucle de eventos se ejecute en breve.

En cuanto al acceso a la cola, tal como está, no hay forma de conocer el estado de la cola fuera del Dispatcher. Este es un detalle interno, y es razonable que no esté expuesto.

+1

Muchas gracias por su respuesta detallada (y perdón por el retraso) –

+1

@Marc No hay problema. :) – Asti

+6

_ "Como consecuencia, solo puede haber un despachador por aplicación." _. <= Eso no es cierto, las instancias del asignador estarán enlazadas a los hilos. Ver el resumen del Dispatcher.CurrentDispatcher: _ "Obtiene el del subproceso que se está ejecutando actualmente y crea uno nuevo si no está asociado con el subproceso". _ Puede imaginar el Dispatcher como una extensión de la bomba de mensajes, la extensión permite ejecutar delega en lugar de solo manejar códigos de mensajes. –

Cuestiones relacionadas