2011-01-21 11 views

Respuesta

7

BackgroundWorker se basa en que se está configurando SynchronizationContext para que funcione. Realmente está destinado y diseñado específicamente para trabajar con el código de UI.

Normalmente es mejor en un servicio autogestionar sus hilos, ya que no hay problemas de sincronización de IU. Usar la API de subprocesos (o la API de tareas de .NET 4) es una opción mucho mejor aquí.

+0

Gracias, Reed. Había leído que solo debería usarse para el código UI, y nunca lo uso en un servicio, pero estamos teniendo una "crisis" aquí en la oficina con algunas personas que dicen "está funcionando durante años" y ese tipo de cosa. Quería darles una opinión independiente sobre el asunto. –

+1

Con el interés de mejorar la capacidad de Otavio para resolver su "crisis", y nuestra edificación, * ¿por qué * está Threading/Task API> BackgroundWorker en un servicio, específicamente? C. Lawrence informa que no hay efectos negativos: ¿qué efectos nocivos son posibles? –

+1

@djacobson: Depende del servicio en cuestión. Si no existe un contexto de sincronización en su lugar, BW solo puede agregar una sobrecarga adicional y no proporcionar beneficios. Si lo está utilizando en un servicio con un SC, como WCF, funcionará como se esperaba, pero en realidad sigue siendo bastante innecesario.Es más fácil simplemente llamar a su método DoWork, y dejar que llame a otros métodos según sea necesario ... –

1

He utilizado BackgroundWorker en servicios de Windows muchas veces sin ningún efecto negativo. Si bien su uso de SynchronizationContext puede ser innecesario, no he observado que cause problemas o un rendimiento deficiente.

2

Bueno, está bien usar un BGW en un servicio, simplemente no hace nada especialmente útil. Su razón de ser es su capacidad para generar los eventos ProgressChanged y RunWorkerCompleted en un hilo específico. Hacer que el código se ejecute en un subproceso específico es algo muy trivial. No puede simplemente insertar una llamada en el hilo mientras está ejecutando el código. Eso causa horribles problemas de reentrada. El hilo debe estar 'inactivo', en un estado donde el código de inyección no causa problemas.

Tener un hilo en un estado inactivo es una condición bastante antinatural. Utiliza hilos para ejecutar el código, no para que ellos giren ociosamente sus talones. Sin embargo, esta es la forma en que funciona un hilo de interfaz de usuario. Pasa el 99% de su tiempo en el ciclo de mensajes, esperando que Windows le diga que haga algo. Un clic de botón, una solicitud de pintura, una pulsación de teclado, ese tipo de cosas. Mientras está dentro del bucle de mensaje, de hecho está inactivo. Un muy buen momento para ejecutar el código inyectado.

que es lo que Winforms 'Control.Begin/Invoke y WPF's Dispatcher.Begin/Invoke do. Ponen un delegado en una cola, la cola se vacía y los delegados se ejecutan por el bucle de mensajes. Las clases WindowsFormsSynchronizationContext y DispatcherSynchronizationContext son los proveedores de sincronización que los utilizan. Winforms y WPF reemplazan SynchronizationContext.Current con una instancia de ellos. Que a su vez es usado por BGW para plantear los eventos. Lo que los hace funcionar en el hilo de UI. Lo que le permite actualizar los componentes de la interfaz de usuario que no son seguros para subprocesos a partir de un subproceso de trabajo.

Probablemente pueda ver hacia dónde se dirige, un servicio no usa ninguno. El proveedor de sincronización predeterminado no sincroniza nada. Simplemente utiliza un subproceso de subprocesos para llamar a la devolución de llamada de envío o publicación. Que es lo que sucederá cuando uses BGW en un servicio. Ahora realmente no tiene sentido tener estos eventos. También podría dejar que el controlador DoWork llame directamente a los métodos de gestión de eventos. Después de todo, el hilo en el que se ejecuta DoWork también es otro hilo de subprocesamiento.

Bueno, no hay daño real, aparte de hacerlo un poco más lento.

Cuestiones relacionadas