2008-09-22 9 views
10

Necesito tener una señal de hilo otra si el usuario desea interrumpir la ejecución, sin embargo no estoy seguro sobre cómo implementar el mecanismo de señalización/verificación de señal. No me gustaría tener un singleton en mi proyecto (como un bool global), pero ¿hay alguna alternativa?¿Cuál es la mejor manera de hacer que un hilo indique otro hilo en .NET?

En this thread personas sugieren estructuras adecuadas para eso en C++, pero no conozco nada similar en .NET. ¿Podría alguien por favor arrojar algo de luz?

Respuesta

7

Pruebe BackgroundWorker. Es compatible con las actualizaciones de progreso y la cancelación de una tarea en ejecución.

Si desea que un subproceso espere hasta que otro subproceso haya terminado de hacerlo, entonces Monitor.Wait y Monitor.Pulse son buenos, como es ManualResetEvent. Sin embargo, estos no son realmente útiles para cancelar una tarea en ejecución.

Si desea escribir su propio código de cancelación, puede simplemente tener un campo en el que ambos subprocesos tengan acceso. Marcos es volátil, por ejemplo .:

private volatile bool cancelling; 

Tener el hilo principal ponemos a true, y tienen el subproceso de trabajo que compruebe periódicamente y lo puso en false cuando se ha terminado.

Esto no es realmente comparable a tener una 'variable global', ya que aún se puede limitar el alcance de la variable de semáforo para que sea privado para una clase.

+0

Preferiría ir con soluciones de framework. ¿La var compartida no huele como un singleton? ¡Gracias por la respuesta! –

+0

BackgroundWorker es parte del framework (2.0, creo). Estoy de acuerdo en que una variable compartida es una solución maloliente para el problema. – Will

+0

Oh, no, en realidad estoy tendiendo a ir con el enfoque BW. La referencia de un-frameworkey fue hacia la implementación de mi propio infierno privado :) –

-2

Mire el espacio de nombres System.Runtime.Remoting.

+2

... Y luego huye gritando. – Will

+1

... y luego se preguntan qué tiene que ver con su pregunta. –

5

Un poco vago (falta de tiempo), pero mira en ManualResetEvent and AutoResetEvent. También es posible que desee buscar Monitor y bloquear palabra clave.

+0

El problema con esto es que alguien debe sentarse esperando que se establezca o debe sondear para que se establezca. El hilo "principal" no se puede sentar, y no quiero un sondeo, pérdida de batería, consumo de energía, sondeo. –

+0

Actually ManualResetEvent o WaitHandle (su base) en usos WaitForSingleObject. Su hilo se suspenderá hasta que llegue la señal. Esto desperdicia algunos ciclos en el cambio de contexto y tiene ~ 100 ms de latencia, pero no desperdiciará ningún ciclo hasta que se indique el hilo. Oh: lo siento, no vi la fecha de esto. –

3

Mire en Monitor.Wait y Monitor.Pulse. Aquí hay un excelente artículo sobre enhebrado en .Net (muy legible): http://www.albahari.com/threading/part4.aspx

+0

Monitor.Wait y Monitor.Pulse no son realmente aplicables al escenario de cancelación. –

+0

El problema con esto es que alguien debe sentarse a esperar que se establezca o debe sondear para que se establezca. El hilo "principal" no se puede sentar, y no quiero un sondeo, pérdida de batería, consumo de energía, sondeo. –

1

Una solución simple, como un booleano estático sincronizado, debe ser todo lo que necesita en lugar de una solución basada en el marco que puede ser exagerada para su escenario . En caso de que aún desee un marco, eche un vistazo a parallel extensions to .NET para obtener ideas.

+0

En realidad, adaptar mi proyecto para aprovechar el BackgroundWorker probablemente traerá más beneficios, ya que tiene algunas abstracciones útiles. Pero si fuera algo realmente simple, ¡no lo pensaría dos veces antes de hacer un bool volátil! –

+0

¿Pero cómo es que el hilo "principal" indica que algo ha sucedido? No sabe que se ha establecido una variable booleana. –

+0

El hilo principal tendría que sondear el campo booleano, normalmente en un bucle. –

1

Depende del tipo de sincronización que necesite. Si desea poder ejecutar el hilo en un bucle hasta que se alcance algún tipo de final de ejecución, todo lo que necesita es una variable bool estática. Si desea que un subproceso espere hasta que otro subproceso llegue a un punto en ejecución, es posible que desee utilizar WaitEvents (AutoResetEvent o ManualResetEvent). Iflyyou need to wait for multiple waitHandles puede usar WaitHandle.WaitAll o WaitHandle.WaitAny.

+0

ya tengo una lista, que podría verificar si contiene más de cero elementos. El problema es indicarle al hilo principal que la lista tiene más de cero elementos o, alternativamente, que se ha configurado un booleano o se ha configurado un evento, mutex o teléfono móvil. –

Cuestiones relacionadas