2009-08-24 24 views
6

Desidero attendere 15 secondi, quindi il controllo dovrebbe riprendere dalla successiva istruzione.Qual è il modo migliore per aspettare un certo tempo (diciamo 10 secondi) in C#?

Non ho nient'altro da fare mentre aspetto (Sto solo aspettando).

So che c'è Thread.Sleep(15000). Quello che non so è il metodo migliore per aspettare? Quali sono i limiti di questo?

Il codice dovrebbe essere simile a questo:

Method() 
{ 
    statement 1; 
    statement 2; 
    //WaitFor 15 secs here; 
    statement 3; 
} 
+0

Thread.Sleep (15000) va bene per C#. Per WinForms, WPF o ASP.NET è un disastro. –

+0

Quasi duplicati: http://stackoverflow.com/questions/1091710, http://stackoverflow.com/questions/407130, http://stackoverflow.com/questions/1208103 e http://stackoverflow.com/questions/903.688. –

risposta

2

provare qualcosa di simile al seguente:

void Method() 
{ 
    console.log('statement 1'); 
    console.log('statement 2'); 

    var timer = new System.Threading.Timer(
     o => // timer callback 
     { 
      console.log('statement 2'); 
     }, 
     15000, // Delay 
     0  // Repeat-interval; 0 for no repeat 
    ); 
} 

sintassi è C# 3.0, utilizza un'espressione lambda per creare in modo efficace una chiusura attorno dichiarazione 3 #. Con questo, è possibile utilizzare qualsiasi variabile locale del metodo. Una cosa da notare, tuttavia, è che con questo metodo, o con qualsiasi altro metodo basato sul timer ... la funzione ritornerà immediatamente dopo aver creato il timer. La funzione non si bloccherà fino all'esecuzione del timer.Per riuscirci, l'unica cosa che posso pensare è di usare effettivamente i thread e fare in modo che Method() blocchi su un segnale (ad esempio WaitHandle, ResetEvent, ecc.) Finché la chiamata temporizzata sull'altro thread non sia completata.

+4

C'è un problema con questo esempio. Non funzionerà in modo affidabile, poiché nessun riferimento all'oggetto 'Timer' viene mantenuto ovunque. Pertanto, è soggetto alla raccolta dei rifiuti. Più lungo è il tuo ritardo, più probabilmente questo sarà un problema. Da MSDN: * Finché si utilizza un timer, è necessario mantenere un riferimento ad esso. Come con qualsiasi oggetto gestito, un Timer è soggetto alla garbage collection quando non ci sono riferimenti ad esso. Il fatto che un timer sia ancora attivo non impedisce che venga raccolto. * – Thorarin

+0

@Thorarin: Ah, buon punto. Ho dimenticato tutto di quel piccolo fatto. Vedrò se posso correggere l'esempio. – jrista

+0

Se si desidera richiamare la chiamata sul thread dell'interfaccia utente, è necessario utilizzare 'System.Windows.Forms.Timer'. –

1

Si può sempre utilizzare un timer e quindi eseguire codice dopo la durata impostata. Tuttavia, se in realtà non devi fare nulla e vuoi solo aspettare un particolare punto del codice, allora penso Thread.Sleep (150000); è sufficiente. [Modifica: ortografia]

2

Thread.sleep sembra una cosa sensata da fare se non c'è altro da fare in attesa. Mette il thread in stop per quel tempo, quindi non utilizza risorse della CPU.

+0

Sì, qualsiasi altro metodo utilizzerebbe la CPU e non lo si desidera, se tutto ciò che si deve fare è attendere ... – awe

+0

È particolarmente utile nei test delle unità in cui è necessario simulare il delta temporale. Il metodo non può uscire in modo che Thread.Sleep() sia meno malvagio in questa particolare situazione. Per lunghi intervalli di tempo, ho modificato l'ora del sistema. Un po 'come mettere il computer in una macchina del tempo. Al termine del test, il sistema ritorna normale. –

11

Lo svantaggio di Thread.Sleep è se questo viene chiamato nel thread della GUI (il thread che elabora gli eventi della GUI, ad esempio un metodo di gestione del clic del pulsante o un metodo chiamato da un gestore di clic del pulsante, ecc.) Quindi l'applicazione sembrerà bloccarsi e non rispondere per quei 15 secondi.

Sarebbe perfetto se tu avessi creato esplicitamente un thread separato e chiamato Thread.Sleep in esso, supponendo che non ti dispiaccia che quel thread non stia facendo nulla per 15 secondi.

L'alternativa sarebbe quella di creare un timer e avviarlo dopo lo stmt 2 e posizionare stmt 3 nel gestore dell'evento tick per il timer e anche arrestare il timer in quel gestore.

6

Questa potrebbe non essere una risposta diretta alla tua domanda. Direi di controllare se il tuo flusso di processo è meglio che controllare se il codice è migliore ;-)

Stai aspettando 15 secondi solo per essere sicuro di stmt2; è completo? Se è così, l'aggiunta di un gestore, non appena stmnt 2 viene eseguita, sarebbe una soluzione migliore (?)

È inoltre possibile utilizzare un timer per attendere. Thread.sleep è un cattivo design. Abbiamo una domanda simile che parla dello comparison using Thread.sleep and Timer.

0

Se si desidera sempre attendere un dato orario, è utile Sleep. Ovviamente non dovresti farlo su un thread in cui sono previste risposte tempestive.

Ricordare che il thread interromperà la durata in tutti i casi. Se per qualche motivo vuoi che il thread riprenda prima, è meglio usare segnali o callback. Utilizzando uno di questi al posto di Sleep, ridurrete al minimo il tempo di attesa inutile.

-1

non fare sicuro al 100%, ma se si ha realmente bisogno il metodo per tornare dopo aver atteso 15 secondi, prova a seguire:

 

Method() 
{ 
    stmt1(); 
    stmt2(); 

    int time = DateTime.Now.Millisecond; 
    while (15*1000 > DateTime.Now.Millisecond - time) 
    { 
     Thread.Sleep(10) 
     Application.DoEvents(); 
    } 
    stmt3(); 
} 
 
0
void Method() 
{ 
    Statement1(); 
    Statement2(); 

    // Start the timer for a single 15 second shot. 
    // Keep a reference to it (Mytimer) so that the timer doesn't get collected as garbage 
    Mytimer = new System.Threading.Timer((a) => 
     { 
      // Invoke the 3rd statement on the GUI thread 
      BeginInvoke(new Action(()=>{ Statement3(); })); 
     }, 
    null, 
    15000, // 15 seconds 
    System.Threading.Timeout.Infinite); // No repeat 
} 
Problemi correlati