2012-11-15 8 views
19

Ho un'applicazione per console che vorrei tenere aperto tutto il tempo mentre ascolto ancora gli eventi. Ho testato Thread.Sleep(Timeout.Infinite); e while (true) { } e entrambi consentono di sollevare gli eventi mantenendo aperta l'applicazione della console. C'è uno che dovrei usare sull'altro? Se il thread sta dormendo, c'è qualcosa che non dovrei fare, come modificare una collezione statica dichiarata nell'ambito della classe?Is Thread.Sleep (Timeout.Infinite); più efficiente di while (true) {}?

risposta

22

Ti consiglio di utilizzare un ManualResetEvent (o altro WaitHandle), e chiamando ManualResetEvent.WaitOne.

Ciò avrà un effetto simile a dormire per sempre, a meno che vi offre un modo pulito per uscita dal "blocco" infinito quando desiderato (chiamando Set() sull'evento).

L'utilizzo di while(true) consuma i cicli della CPU, quindi è sicuramente qualcosa da evitare.

c'è qualcosa che non dovrei fare, come la modifica di una raccolta statica dichiarata nell'ambito della classe?

In generale, n. Poiché il tuo thread sarà bloccato, non ci dovrebbero essere problemi di sincronizzazione con l'utilizzo di dati condivisi (a condizione che gli elementi all'interno della raccolta non abbiano requisiti specifici, come gli elementi dell'interfaccia utente che devono essere utilizzati su un thread con un contesto di sincronizzazione appropriato .)

+0

In realtà non voglio affatto che esca, ma accetterò la tua risposta nel caso in cui ci siano persone in cerca che desiderano avere un modo per uscire. – Lunyx

+0

@Daniel È bello avere un modo pulito per il tuo programma di spegnersi * alla fine *, anche se non è qualcosa che vuoi in un momento specifico;) Detto questo, utilizzerei comunque questo approccio per un sonno, personalmente. –

+0

In che modo l'utilizzo di ManualResetEvent equivale a Thread.Sleep() se l'unica volta che si chiude il programma si verifica al riavvio della macchina? – Lunyx

4

A differenza di while(true)..., Thread.Sleep non utilizza i cicli della CPU, quindi in questo senso, il sonno è più efficiente. In generale, l'utilizzo di Busy Waiting al di fuori di spinlocks è fortemente sconsigliato.

Se il thread sta dormendo, c'è qualcosa che non dovrei fare?

Poiché il thread è bloccato all'entrata in Thread.Sleep, tutto ciò che si desidera fare alle sue risorse è un gioco leale.

+0

Grazie, ho visto il ciclo while essere consigliato a persone che cercano di realizzare quello che sto facendo e non ero sicuro se questo era il modo corretto di procedere. – Lunyx

2

, while(true) consuma CPU mentre sleep() opere in un modo più intelligente: La funzione sleep() mette il contesto di esecuzione corrente a dormire; lo fa chiamando una chiamata di sistema per richiamare la funzione di spegnimento del kernel che atomicamente
(a) imposta un timer sveglia
(b) i marchi del processo corrente come dormire
(c) attende che i fuochi d'allarme-timer o si verifica un'interruzione

Se si chiama sleep(), la CPU può eseguire altre operazioni.

Questo è uno dei motivi per cui sleep() è utile.

Un link utile - Be careful when using Sleep

3

penso che la chiamata

while (true) { ... } 

è computazionalmente intensive, dal momento che il filo non si ferma mai, wheareas

Thread.Sleep(Timeout.Infinite); 

in realtà ottiene il filo a dormire con l'aiuto dei pianificatori native del sistema operativo. E poi il thread si ferma effettivamente, quindi suppongo che sia meno impegnativo dal punto di vista computazionale.

+2

Sembra esserci incertezza nella risposta ... "Penso", "Suppongo", ecc. –

+0

ero sicuro della risposta, ma ho appena iniziato una carriera in java, ecco perché ho usato "Penso", "Suppongo "per precauzione. :) – leoismyname