2011-01-06 18 views
8

Estoy un poco confundido en términos de despachador. Supongamos que estoy en un hilo de fondo realizando algún tipo de operación larga. Me gustaría actualizar el hilo de la interfaz de usuario entiendo que lo hago a través del despachador. Mi pregunta es, ¿llamo al despachador estáticamente como: Dispatcher.BeginInvoke (mywork) ... O en el control que quiero actualizar: mytextbox.Dispatcher.BeginInvoke (mywork)WPF/threading: Dispatcher estático frente a Dispatcher en un control?

Respuesta

0

Primero, creo que es importante entender , que el Dispatcher no está diseñado para manejar grandes operaciones en segundo plano. Está diseñado para cola de trabajo en el subproceso de interfaz de usuario de un objeto. Aquí está un artículo que vale la pena MSDN sobre el modelo de enhebrado .NET y Dispatcher:

diciendo que la forma estándar de la realización del procedimiento Dispatcher.BeginInvoke sería llamarlo en el mando:

startStopButton.Dispatcher.BeginInvoke(
    DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber) 
); 

Espero que ayude!

14

Vale la pena señalar que llamar Dispatcher.BeginInvoke no es una llamada estática: es una implícita this.Dispatcher.BeginInvoke. Si puede usar esta llamada, probablemente ya esté escribiendo su código desde un control o ventana. En ese caso, es probablemente seguro para llamar ya que la mayoría de las veces habrá un subproceso de interfaz de usuario por aplicación.

La llamada estática real sería Dispatcher.CurrentDispatcher.BeginInvoke, que es no algo que desea llamar (ver mi comentario sobre la respuesta de Hasan Khan por qué).

EDIT: Llamar aApplication.Current.Dispatcher es no es algo malo. (Y, para mayor claridad, es una propiedad de instancia, no una estática, que se llama en una instancia estática/singleton de Application). Esta propiedad devolverá el despachador para el subproceso con el que se creó la aplicación, y normalmente ese es el hilo que el La IU también se crea, por lo que Application.Current.Dispatcher devuelve el mismo despachador como myWindow.Dispatcher.

La llamada estática Dispatcher.CurrentDispatcher (que advertí en contra) devuelve un despachador para el hilo desde el que lo llama. Si lo llamas desde un hilo de fondo, obtendrás un nuevo Dispatcher creado especialmente para ese hilo, que a menudo no es lo que se quiere.

+0

* ¿Por qué * está usando 'Application.Current.Dispatcher' una mala idea? Lo uso en mi aplicación sin problemas hasta el momento. Todo lo que se requiere es que 'Application(). Run()' haya sido llamado. – Aphex

+0

@Aphex: He respondido como una edición, ya que no podía encajarlo en el comentario, pero no hay nada de malo con 'Application.Current.Dispatcher' (y no había dicho que existiera). 'Application.Current.Dispatcher' y' Dispatcher.CurrentDispatcher' se comportan de manera muy diferente. –

+0

Hay casos en los que el uso de Application.Current.Dispatcher no es seguro (aunque muy raro), p. hospedar el control WPF en WinForms (o cualquier otra aplicación que no sea WPF) (Application.Current is null) o tener varios subprocesos de UI en la misma aplicación (hay muchos problemas con los recursos de la aplicación compartida, pero el caso sigue siendo relevante). Por lo tanto, la forma más segura es usar control.Dispatcher – Aloraman

0

Mientras que en la mayoría de casos utilizando ya sea DispatcherObject.Dispatcher (todos los objetos de dependencia y controles heredan de DispatcherObject, entre otros) o Application.Current.Dispatcher es lo que hay que hacer, ya que por lo general hay sólo un hilo de interfaz de usuario, no puede haber múltiples hilos de interfaz de usuario y diferentes ventanas pueden usar diferentes despachadores. En ese caso, es importante actualizar el control utilizando su despachador. Se almacena en su propiedad Dispatcher (heredada de DispatcherObject), cualquier otro control en esta ventana y la ventana misma.

Cuestiones relacionadas