2011-12-13 3 views
12

Vorrei che il mio metodo attenda circa 500 ms e poi controlli se qualche flag è cambiato. Come completare questo senza bloccare il resto della mia applicazione?C# attendere un po 'senza bloccare

+6

La domanda è profondamente sottostimata; abbiamo bisogno di sapere che cosa "il resto dell'applicazione" è - è in esecuzione sullo stesso thread, thread diversi, una macchina diversa, cosa? Detto questo, quasi tutte le risposte finora sono pericolose. L'utilizzo di DoEvents o Thread.Sleep è una delle peggiori pratiche che indicano un'applicazione mal progettata in pericolo di cattivi bug di re-entrancy. La risposta di Tudor è la migliore: utilizzare un timer. –

+4

Inoltre, si consideri l'analisi della versione Async CTP di C# 5. Abbiamo aggiunto il flusso di controllo che consente di ritardare facilmente per 500 millisecondi e riprendere da dove si era interrotto, senza bloccare alcun thread o avviare nuovi loop di messaggi. –

risposta

25

Thread.Sleep (500) imporrà il thread corrente ad attendere 500ms. Funziona, ma non è quello che vuoi se l'intera applicazione è in esecuzione su un thread.

In tal caso, ti consigliamo di utilizzare un timer, in questo modo:

using System.Timers; 

void Main() 
{ 
    Timer t = new Timer(); 
    t.Interval = 500; //In milliseconds here 
    t.AutoReset = true; //Stops it from repeating 
    t.Elapsed += new ElapsedEventHandler(TimerElapsed); 
    t.Start(); 
} 

void TimerElapsed(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine("Hello, world!"); 
} 

È inoltre possibile impostare AutoReset su false (o non impostato affatto) se si desidera che il timer a ripetersi .

+2

Solo una leggera correzione, la proprietà "Intervallo" ha un valore in ** millisecondi **, non secondi [collegamento] (http://msdn.microsoft.com/en-us/library/system.timers.timer.interval (v = vs.110) .aspx) –

+0

** thread corrente ** è stato molto utile. erroneamente pensato che 'Thread.Sleep' causi la sospensione del thread principale –

+0

Penso che tu abbia l'uso di AutoReset all'indietro Impostandolo su true o non impostandolo affatto, il timer si ripete da solo. [link] (https: // msdn.microsoft.com/en-us/library/s ystem.timers.timer.autoreset% 28v = vs.110% 29.aspx? f = 255 & MSPPError = -2.147,217396 millions) – JochemKempe

5

E 'il metodo in questione è in esecuzione su un thread diverso rispetto al resto della vostra applicazione, quindi effettuare le seguenti operazioni:

Thread.Sleep(500); 
+1

che ne dici se tutto funziona su un thraed? – santBart

+0

@ user898569 per definizione se si desidera "aspettare qualcosa" qualcosa deve stare lì "in attesa". Quindi no, devi usare un altro thread o bloccherà il tuo programma. Vedi [risposta di Tudor] (http://stackoverflow.com/a/8496300/80274) per un modo per attivare un evento che verrà eseguito sul thread principale ma che non sarà "in attesa", sarà solo un evento periodico. –

+0

Interessante domanda. Ti suggerisco di leggere su Asynchronous Programming in .NET. Ecco un link a un buon punto di partenza: http://msdn.microsoft.it/it/us/vstudio/gg316360 –

2
System.Threading.Thread.Sleep(500); 

Aggiornamento

Questo non bloccherà la resto dell'applicazione, solo il thread su cui è in esecuzione il metodo.

+0

in alternativa? – santBart

+0

Lol, il mio ha impiegato più di 7 secondi per scrivere perché ho inserito lo spazio dei nomi. Non era il primo :( – danludwig

7

Non capisco davvero la domanda.

Se si desidera bloccare prima di controllare, utilizzare Thread.Sleep(500);

Se si desidera controllare in modo asincrono ogni x secondi, è possibile utilizzare un Timer per eseguire un gestore ogni x millisecondi.

Questo non bloccherà il thread corrente.

+1

Penso che questo sia ciò di cui l'OP ha bisogno – Otiel

+0

Se si tratta di un'applicazione GUI, probabilmente è meglio usare il timer specifico per la libreria della GUI usata (ad esempio 'DispatcherTimer' nel caso di WPF.) – svick

+0

C'è una differenza tra "controllare ogni x secondi" e "aspettare x secondi e poi controllare". Credo che l'OP voglia il secondo –

0

Utilizzando un timer dovrebbe fare il trucco

se è necessario utilizzare un filo allora ecco un esempio

void Main() 
{ 
    System.Threading.Thread check= new System.Threading.Thread(CheckMethod); 
    check.Start(); 
} 

private void CheckMethod() 
{ 
    //Code 
    Thread.Sleep(500); 
} 
0

Asynchron Task:

var task = new Task (() => function_test()); task.Start(); 

public void function_test() { `Wait for 5000 miliseconds` Task.Delay(5000);` } 
2

È possibile utilizzare await Task.Delay(500); senza bloccare il thread come Sleep fa e con molto meno codice di un timer.