2011-12-21 5 views
6

Generalmente con i servizi, l'attività che si desidera completare viene ripetuta, forse in un ciclo o forse un trigger o forse qualcos'altro.Topshelf - handling loops

Sto utilizzando Topshelf per completare un'attività ripetuta per me, in particolare sto utilizzando la funzionalità Shelf'ing.

Il problema che sto avendo è come gestire il loop dell'attività.

Quando avvio reggette il servizio in TopShelf, si passa una classe (in questo caso ScheduleQueueService) e indicare che è il suo metodo Start ed è Stop metodo:

Esempio:

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()); 
    } 
} 

Ma in il mio metodo StartService() Sto usando un ciclo while per ripetere l'attività che sto eseguendo, ma quando tento di interrompere il servizio tramite i servizi Windows non si ferma e sospetto che sia perché il metodo StartService() non è mai terminato quando è stato chiamato originariamente.

Esempio:

public class ScheduledQueueService 
{ 
    bool QueueRunning; 

    public ScheduledQueueService() 
    { 
     QueueRunning = false; 
    } 


    public void StartService() 
    { 
     QueueRunning = true; 

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

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

ciò che è un modo migliore di fare questo?

  1. Ho considerato utilizzando .NET System.Threading.Tasks per eseguire il lavoro e poi forse la chiusura del thread su StopService()

  2. Forse usando Quartz di ripetere l'operazione e poi rimuoverlo.

Pensieri?

risposta

0

Non so su Topshelf in modo specifico ma quando si scrive un servizio Windows standard si desidera che gli eventi di avvio e arresto vengano completati il ​​più rapidamente possibile. Se il thread di avvio impiega troppo tempo, Windows presume che non sia stato avviato, ad esempio.

Per aggirare questo uso generalmente un System.Timers.Timer. Questo è impostato per chiamare un metodo di avvio solo una volta con un intervallo molto breve (quindi viene eseguito quasi immediatamente). Questo poi fa la maggior parte del lavoro.

Nel tuo caso, questo potrebbe essere il tuo metodo che è in loop. Quindi all'inizio di ogni ciclo controlla una variabile di spegnimento globale - se è vera, esci dal ciclo e poi il programma può fermarsi.

Potrebbe essere necessario un po 'più (o forse anche meno) complessità di questo a seconda di dove esattamente l'errore è, ma il principio generale dovrebbe andare bene spero.

Ancora una volta, tuttavia, deciderò che questa conoscenza non è basata su topshelf, ma sullo sviluppo di servizi generali.

+0

Dopo tutti questi anni, qualcuno sa se è davvero anche il caso di Topshelf? Non c'è traccia di ciò nella documentazione di Topshelf e sto faticando a decidere se dovrei generare in modo sistematico un nuovo thread o qualcosa di simile su WhenStarted() nel mio servizio. – guillaume31

3

In genere, come gestirlo è un evento Timer, che si attiva pochi istanti dopo la chiamata a StartService(). Alla fine dell'evento, controllerei il flag stop (impostato su StopService()), se il flag (ad esempio il tuo QueueRunning) non è presente, quindi registrerei un singolo evento sul timer per ricominciare tra qualche istante .

Facciamo qualcosa di molto simile a TopShelf sé, quando il polling del file system: https://github.com/Topshelf/Topshelf/blob/v2_master/src/Topshelf/FileSystem/PollingFileSystemEventProducer.cs#L80

Ora che utilizza il tipo di pianificazione interna invece di un oggetto Timer, ma in generale è la stessa cosa. Il fiber è fondamentalmente il thread su cui elaborare l'evento.

Se avete domande future, siete anche i benvenuti a iscrivervi alla mailing list di Topshelf. Cerchiamo di essere abbastanza reattivi lì. http://groups.google.com/group/topshelf-discuss

+0

il primo link è rotto – SteveC

+2

Hai ragione SteveC. Fisso! – Travis