2009-06-24 18 views
6

En WinForms, tiene Control.BeginInvoke(), lo que significa que puede ordenar una llamada desde un subproceso en segundo plano al subproceso de la IU principal que creó el identificador del control.Marshall a un subproceso manualmente

Esto está bien, pero ¿cómo (en C#) haría esto entre dos hilos "estándar"?

He escrito un bus de servicio, que tiene un hilo de procesador para consumir mensajes. Quiero un temporizador para disparar, que hace que el hilo del procesador haga algo, en lugar del código que se ejecuta en el hilo del temporizador.

Por supuesto que puedo usar sincronización de hilos (Monitor/using() {...}) pero me preguntaba cómo se hacía normalmente.

Respuesta

11

Lamentablemente, la respuesta es difícil de dar aquí porque depende en gran medida de la naturaleza del hilo.

Marcar entre hilos no es mágico. Hay un mecanismo subyacente que lo hace posible. Por ejemplo, en WinForms, las funciones de estilo Control.Invoke funcionan a través del envío de mensajes. Hay un mensaje publicado en el hilo de la interfaz de usuario, la bomba de mensaje finalmente bombeará este mensaje y lo convertirá en una llamada de Mariscal.

Para ordenar una llamada entre una cadena de caracteres estándar, debe tener alguna capacidad para detectar que una llamada de agente desea pasar y luego realizar esa llamada. Esto normalmente se hace mediante el envío de mensajes de algún tipo.

En mi humilde opinión, la forma más estándar de hacer esto es haciendo que su hilo implemente, proporcione e instale un SynchronizationContext. Esta es una forma más estándar de definir un mecanismo de Marshaling entre hilos.

+1

SynchronizationContext fue la respuesta que estaba buscando, ¡gracias! –

1

Windows Forms ejecuta un message loop, por lo que puede usar el hilo de la interfaz de usuario para todo tipo de tareas: busca mensajes en su cola, que pueden enviarse a través de los límites de subprocesos.

Si desea hacerlo manualmente, cree su propio bucle de mensajes (para uno o más hilos) o mucho más simple, use primitivas de sincronización. AutoResetEvent parece ser apropiado para esta situación. Solo necesita llamar a los métodos Set y WaitOne en los puntos correctos, realmente (y tenga en cuenta los bloqueos, por supuesto).

Cuestiones relacionadas