2009-06-15 3 views
12

Scrivo un servizio di Windows che deve dormire per lunghi periodi di tempo (15 ore è il più lungo che dormirà, 30 minuti è il più breve). Attualmente sto utilizzando Thread.Sleep (calcolateTime) per mettere il mio codice in modalità di sospensione. Thread.Sleep è l'opzione migliore o dovrei utilizzare un timer? Ho cercato su Google per un po 'e non riesco a trovare una risposta concisa. Poiché si tratta di un servizio di Windows, non devo preoccuparmi di bloccare l'interfaccia utente, quindi non riesco a pensare a un motivo per non utilizzare Thread.Sleep.Utilizzo di Thread.Sleep() in un servizio di Windows

Qualsiasi intuizione sarebbe apprezzata.

risposta

19

Vorrei utilizzare un timer, Thread.Sleep, potrebbe causare un blocco che potrebbe impedire il servizio di arresto.

Se l'intervallo è così ampio e regolare, è possibile anche solo programmarlo. Ma se stai parlando di intervalli lunghi e non coerenti, allora sì, un timer sarebbe meglio.

7

In molti casi, in genere è consigliabile utilizzare lo Thread.Sleep().

Se si desidera che il servizio venga eseguito in background, è necessario utilizzare un timer.

Se il servizio deve essere eseguito solo a intervalli pianificati, ti consiglio di utilizzare l'utilità di pianificazione di Windows per consentire a Windows di eseguire l'applicazione quando ne hai bisogno.

5

Non dovresti calcolare in anticipo una quantità così grande di tempo e dormire per ore. Dormi per un minuto al massimo, poi svegliati e ricalcoli l'ora, dormi ancora per non più di un minuto. Presumo che il calcolo sia molto economico o che possa essere reso molto economico con il caching. Il problema che il mio consiglio sta tentando di mitigare è che gli orologi dei computer sono sorprendentemente "saltellanti", principalmente a causa della deriva temporale corretta dal servizio di orari di rete, anche a causa del risparmio di luci diurne e non ultimo perché l'utente regola l'orologio. Quindi è meglio ricalcolare costantemente il tempo per intervalli così lunghi, anche se significa svegliarsi ogni minuto o così. E non essere sorpreso (ad esempio non asserire) se ti svegli nel 'passato', gli orologi possono adattarsi indietro nel tempo.

1

Un'altra cosa da considerare è che i thread sono risorse limitate e ogni thread consuma una porzione di memoria (1 MB) per il relativo stack. Possono anche aumentare il carico per lo scheduler.

Ora, se il vostro servizio non sta facendo molto altro, lo spazio sprecato è banale, ma è bene essere consapevoli di ciò prima di iniziare ad allocare più thread. Usare un ThreadPool e/o Timer è molto più efficiente.

9

Poiché un servizio può chiedere di interrompere in qualsiasi momento dal responsabile del controllo servizi, il thread deve sempre essere pronto a rispondere a tali richieste, quindi non utilizzare Thread.Sleep(). Invece, creare un evento di reset manuale nel thread principale e utilizzare il suo metodo WaitOne con un timeout nel thread di lavoro. WaitOne restituirà false quando scade il tempo.

Quando vengono chiamati i metodi OnStop o OnShutdown della classe di servizio, impostare l'evento e questo causerà la restituzione di WaitOne true e quindi è possibile uscire dal thread di lavoro.