2010-05-21 16 views
6

ho bisogno di un certo modo di fare le seguenti efficiente in C#:C# stop e continuare

far fermare l'esecuzione del programma fino a certo valore viene modificato.

Nota: Non voglio farlo con un ciclo while per evitare di sprecare la potenza della CPU ..

Edit: E voglio di rispondere il più rapidamente possibile dopo valore è cambiato ..

Edit: Questo sarà dentro la mia metodo di classe che viene chiamato da un altro codice, tuttavia il valore da controllare è dentro la mia classe ... il metodo dovrebbe aspettare fino a quando altri c ode valutare e cambiare il mio valore .. poi si deve continuare a fare il suo lavoro .. molte volte, purtroppo, questo viene fatto (quindi ho bisogno di cura per le prestazioni)

+0

È questa applicazione un servizio di Windows? Non si specifica e non ha realmente senso sospendere letteralmente l'esecuzione in un'applicazione interattiva (basata su eventi). – Aaronaught

+5

I tuoi requisiti sono contraddittori.Respingi l'attesa attenta a causa del suo consumo di energia, e richiedi che sia il più reattivo possibile **, ma l'attesa è quella che sarà ** più reattiva possibile **. Cosa sarebbe meglio se ci parlassi del tuo * budget *. "Il più veloce possibile" non ci dice nulla; "entro un millesimo di secondo" ci dice molto. Una soluzione che risponda entro un millisecondo potrebbe essere piuttosto diversa da una soluzione che risponda a un microsecondo o ad un secondo. –

+1

cosa intendi esattamente facendo fermare l'esecuzione? è un thread in esecuzione costante che devi interrompere ad un certo punto? come intendi farlo smettere? o è più simile a un breve evento che ti piacerebbe accadere in un cambiamento di valore? –

risposta

15
+0

Non c'è 'Monitor.Set'. Intendevi 'Monitor.Pulse' o' Monitor.PulseAll'? – Aaronaught

+0

@ Aaronaught- sì, sì –

+0

Se vuoi dormire completamente senza spinning, questa è la strada da percorrere. Tuttavia, ciò richiede che il codice che imposta il valore sappia come pulsare sull'oggetto corretto, altrimenti il ​​codice non si riattiverà mai. – Stephan

6
while(some-condition-here) 
{ 
    Thread.CurrentThread.Sleep(100); // Release CPU for 100ms 
} 

Si chiama spin-sonno credo. Ovviamente puoi aggiustare il 100 a qualsiasi cosa tu ritenga sia adatto. In pratica è il timeout per ogni controllo.

Ci sono altri modi per farlo, ma questo è il più semplice ed è abbastanza efficiente.

In realtà è fatto riferimento in questo e-book:

Threading in C# by Joseph Albahari: Part 2: Basic Synchronization

+0

L'ho usato prima, ma non ne sono un fan. (quindi non modifico la tua risposta in alto o in basso.) Mi ha sempre "odorato". – Pretzel

+0

@Pretzel Ho fatto riferimento a un libro (e-book) che ne parla. – Aren

+0

Solo perché in un libro non è corretto. Inoltre, per citare l'autore, "Forse il suo più grande uso è quando un programmatore ha rinunciato a ottenere un costrutto di segnalazione più complesso per funzionare!" –

7

Se il valore che stai aspettando è impostato da qualche altra parte nella stessa applicazione è possibile utilizzare una maniglia di attesa:

AutoResetEvent waitHandle = new AutoResetEvent(); 
... 
//thread will sleep here until waitHandle.Set is called 
waitHandle.WaitOne(); 
... 
//this is where the value is set 
someVar = someValue; 
waitHandle.Set(); 

(notare che il WaitOne e Imposta devono verificarsi su thread separati come WaitOne volontà

Se non si ha accesso al codice che modifica il valore, il modo migliore per farlo è, come altri hanno detto, utilizzare un ciclo per verificare se il valore è cambiato e utilizzare Thread.Sleep() in modo da non utilizzare tutto il tempo del processore:

while(!valueIsSet) 
{ 
    Thread.Sleep(100); 
} 
+0

/agree ... questo è il miglior modo possibile – csauve

+0

Se l'obiettivo è BLOCARE un thread, questo è il modo migliore. Per bloccare il thread principale ed evitare nuovi input fino a quando l'evento si verifica, posiziona .WaitOne() nella discussione principale. In un altro thread, dove il valore che attiva la sveglia, posiziona .Set(); – Roast

3

È possibile utilizzare il modello di progettazione Observer. È progettato per risolvere problemi come il tuo.

Questo schema contiene principalmente un soggetto e un osservatore. Puoi farlo per rispondere a qualsiasi cambiamento e molto rapidamente.

È possibile trovare ulteriori informazioni e codice di esempio here

+0

Se l'architettura lo consente (ad esempio, hai il controllo su ciò che stai monitorando), questa può essere una buona soluzione. Hai una risposta molto veloce perché ricevi l'evento subito dopo la modifica. L'avvertimento principale è che si sta eseguendo nel contesto del thread che ha eseguito il cambiamento, che a volte può essere problematico. –