2012-02-09 7 views
7

Sono stato recentemente sfidato a scrivere un servizio di Windows. Avevo bisogno di richiedere periodicamente un URL e verificarne la disponibilità. Per questo ho deciso di inizializzare un timer nel metodo OnStart del servizio e fare tutto il lavoro nell'evento timer_Tick.Perché il servizio Windows non funziona correttamente con System.Timers.Timer o System.Windows.Forms.Timer

Il mio primo approccio era usare System.Windows.Forms.Timer e il suo evento Tick. Ho scelto per questo, a causa del tutorial che stavo leggendo. In qualche modo non ho potuto far funzionare il servizio. Si è installato e avviato senza problemi, ma non ha attivato l'evento (ho collegato il debugger al processo e ho visto che non è stato attivato). Ho pensato che forse usare il timer di Forms nel servizio di Windows non è una buona idea, quindi ho deciso di passare a System.Timers.Timer e utilizzare il suo evento Elapsed. Questo non ha funzionato neanche. Ho provato entrambi gli approcci menzionati in un'applicazione Windows Form ed entrambi hanno funzionato.

Dopo alcuni scavi, ho trovato questo sito: http://weblogs.asp.net/sibrahim/archive/2004/01/13/58429.aspx su cui il blogger consiglia di utilizzare un altro timer: System.Threading.Timer. Ho cambiato l'approccio per la terza volta e BOOM ha iniziato a funzionare come un fascino.

La mia domanda è: perché non è possibile utilizzare gli altri timer nei servizi di Windows e perché è così difficile trovare informazioni su di esso?

+1

Ho trovato questo articolo confrontando diversi timer .NET. Sicuramente vale la pena leggere: http://msdn.microsoft.com/en-us/magazine/cc164015.aspx –

+0

Il 'System.Threading.Timer' è l'unico che ha funzionato per me in' Windows Server 2008 R2' anche se Timer. Il timer funzionava con il mio 'Windows 7 laptop'. – Lijo

risposta

8

Il timer System.Windows.Forms.Timer utilizza il messaggio pump dell'interfaccia utente per eseguire il marshalling dell'evento tick, un servizio non esegue un messaggio pump per impostazione predefinita, quindi senza un piccolo lavoro aggiuntivo i timer System.Windows.Forms.Timer non funzioneranno.

Il System.Timers.Timer è un timer basato su server e genera un evento sul thread su cui lo si crea (credo). Se questo non funziona, forse non stai iniziando il timer o il timer gira su un thread che termina immediatamente (come in, nulla mantiene il thread in vita in modo che finisca).

http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

Il System.Threading.Timer timer utilizza un callback che viene eseguito su un thread ThreadPool e non è vincolata alla pompa messaggio a tutti, quindi questo ha funzionato.

Quando si esegue Application.Run(myForm) in un progetto WinForms, quella chiamata esegue anche il messaggio pump, che gestisce i messaggi dell'interfaccia utente. Il timer di Windows che hai menzionato è un componente dell'interfaccia utente e si aspetta che il pump dei messaggi sia in esecuzione per causare l'evento tick nel thread dell'interfaccia utente.

Date un'occhiata qui per l'esecuzione di una pompa di messaggio in un servizio di Windows:

Message pump in .NET Windows service

Ulteriori approfondimenti:

http://support.microsoft.com/kb/842793

In conclusione, vorrei solo andare con il System.Threading.Timer classe.

+2

Entrambi i timer eseguono il codice su un thread del threadpool. Avere l'evento/callback eseguito sullo stesso thread che ha creato il timer richiede la magia. Il tipo di magia che fornisce un messaggio alla pompa. –

Problemi correlati