2011-12-21 11 views
6

En general, con los servicios, la tarea que desea completar se repite, tal vez en un bucle o tal vez un desencadenador o tal vez algo más.Topshelf - manejo de bucles

estoy usando Topshelf para completar una tarea repetida para mí, en concreto estoy usando la funcionalidad Shelf'ing.

El problema que tengo es cómo manejar el bucle de la tarea.

Cuando arranque flejes el servicio en Topshelf, se le pasa una clase (en este caso ScheduleQueueService) e indicar cual es su método Start y es Stop método:

Ejemplo:

public class QueueBootstrapper : Bootstrapper<ScheduledQueueService> 
{ 
    public void InitializeHostedService(IServiceConfigurator<ScheduledQueueService> cfg) 
    { 
     cfg.HowToBuildService(n => new ScheduledQueueService()); 
     cfg.SetServiceName("ScheduledQueueHandler"); 
     cfg.WhenStarted(s => s.StartService()); 
     cfg.WhenStopped(s => s.StopService()); 
    } 
} 

Pero en my StartService() método Estoy usando un ciclo while para repetir la tarea que estoy ejecutando, pero cuando intento detener el servicio a través de los servicios de Windows, no se detiene y sospecho que es porque el método StartService() nunca finalizó cuando se llamó originalmente.

Ejemplo:

public class ScheduledQueueService 
{ 
    bool QueueRunning; 

    public ScheduledQueueService() 
    { 
     QueueRunning = false; 
    } 


    public void StartService() 
    { 
     QueueRunning = true; 

     while(QueueRunning){ 
        //do some work 
     } 
    } 

    public void StopService()  
    { 
     QueueRunning = false; 
    } 
} 

lo que es una mejor manera de hacer esto?

  1. he considerado utilizando .NET System.Threading.Tasks para ejecutar el trabajo y entonces tal vez el cierre de la rosca en StopService()

  2. Tal vez usando Quartz a repetir la tarea y luego eliminarlo.

¿Pensamientos?

Respuesta

0

No sé sobre Topshelf específicamente, pero cuando se escribe un servicio de Windows estándar que desee el inicio y parada eventos para completar lo más rápidamente posible. Si el hilo de inicio toma demasiado tiempo, Windows asume que no se pudo iniciar, por ejemplo.

Para evitar esto generalmente utilizo un System.Timers.Timer. Esto está configurado para llamar a un método de inicio una sola vez con un intervalo muy corto (por lo que se ejecuta casi de inmediato). Esto luego hace la mayor parte del trabajo.

En su caso, este podría ser su método en bucle. Luego, al inicio de cada ciclo, verifique una variable de apagado global: si es cierto, abandone el ciclo y luego el programa puede detenerse.

Es posible que necesite un poco más (o incluso menos) la complejidad que esto dependiendo de dónde está exactamente el error pero el principio general debe estar bien espero.

Una vez más, sin embargo voy a negar que este conocimiento no se basa en el desarrollo de servicios topshelf, jsut general.

+0

Después de todos estos años, nadie sabía si de hecho es también el caso de Topshelf? No hay ningún indicio de que en la documentación Topshelf y yo estoy luchando para decidir si debería generar sistemáticamente un nuevo hilo o algo similar sobre WhenStarted() en mi servicio. – guillaume31

3

En general, la forma en que manejaría esto es tener un evento Timer, que se dispara unos momentos después de llamar al StartService(). Al final del evento, me gustaría comprobar si hay una bandera stop (establecido en StopService()), si el indicador (por ejemplo, su QueueRunning) no está allí, entonces yo sería registrar un evento único en el temporizador a ocurrir de nuevo en unos momentos .

Hacemos algo bastante similar en sí Topshelf, cuando el sistema de archivos de votación: https://github.com/Topshelf/Topshelf/blob/v2_master/src/Topshelf/FileSystem/PollingFileSystemEventProducer.cs#L80

Ahora que utiliza el tipo de programador interno en lugar de un objeto Timer, pero por lo general es la misma cosa. El fiber es básicamente que el hilo para procesar el evento en.

Si tiene preguntas futuras, también son bienvenidos a unirse a la lista de correo Topshelf. Tratamos de ser muy receptivos allí. http://groups.google.com/group/topshelf-discuss

+0

el primer enlace está roto – SteveC

+2

Tienes razón SteveC. ¡Fijo! – Travis