2012-01-10 18 views
8

Sto lavorando a un'applicazione console che verrà pianificata ed eseguita a intervalli prestabiliti, ad esempio ogni 30 minuti. Il suo unico scopo è di interrogare un servizio Web per aggiornare un gruppo di righe del database.Uso accettabile di Thread.Sleep()

L'API del servizio Web consiglia di chiamare una volta ogni 30 secondi e il timeout dopo un intervallo impostato. Il seguente pseudocodice è dato a titolo di esempio:

listId := updateList(<list of terms>) 
LOOP 
    WHILE NOT isUpdatingComplete(listId) 
END LOOP 
statuses := getStatuses(“LIST_ID = {listId}”) 

ho codificato questo grosso modo in C# come:

int callCount = 0; 
while(callCount < 5 && !client.isUpdateComplete(listId, out messages)) 
{ 
    listId = client.updateList(options, terms, out messages); 
    callCount++; 
    Thread.Sleep(30000); 
} 
// Get resulting status... 

è ok in questa situazione per utilizzare Thread.Sleep()? Sono consapevole che non è generalmente una buona pratica, ma leggendo i motivi per non usarlo sembra un utilizzo accettabile.

Grazie.

+1

L'uso di 'Thread.Sleep' è perfettamente accettabile –

+4

L'applicazione della console verrà pianificata ? Perché non pianificarlo solo ogni 30 minuti, se è così? La soluzione migliore sarebbe un servizio Windows che utilizza un timer per chiamare il metodo. – Ray

+0

Perché no? Quali sono le ragioni per non usarlo? –

risposta

6

Thread.Sleep assicura che il thread corrente non ritorni fino a almeno i millisecondi specificati siano passati. Ci sono molti posti in cui è appropriato farlo, e il tuo esempio sembra soddisfacente, supponendo che sia in esecuzione su un thread in background.

Alcuni esempi di posizioni che non si desidera utilizzare: sul thread dell'interfaccia utente o dove è necessario eseguire la sincronizzazione esatta.

+3

Penso che la tua qualifica "assumendo che sia in esecuzione su un thread in background" sia ok, ma in questo caso l'applicazione sembra essere un'applicazione di console che verrà eseguita automaticamente come operazione pianificata, quindi penso che in questo caso non sia necessario assicurati che funzioni su un thread in background. Se si trattasse di un'applicazione interattiva, sarei totalmente d'accordo con la tua qualifica. –

+0

Intendo thread in background con qualsiasi thread in esecuzione in background, ovvero non un thread dell'interfaccia utente. Thread di servizio Considererei thread di background. (Non mi riferisco a 'IsBackground' sugli oggetti thread, che si riferisce semplicemente a come i thread vengono distrutti/ripuliti all'uscita dall'app, IIRC). Oops, non ti ho visto dire Console. Sì, questa è una terminologia discutibile, ma non è davvero un thread in background, giustamente. Potrei quindi sostenere che un'app Console non è così appropriata .. –

+1

Ah, capisco cosa intendi. :) Non intendevo discutere la semantica, ma il tuo commento mi ha fatto capire che in questo caso, il "thread principale" dell'applicazione console potrebbe essere considerato come un thread "di sfondo" perché non c'è interazione con l'utente. –

3

L'obiezione generale contro Sleep() è che spreca una discussione.

Nel tuo caso c'è solo 1 Thread (forse 2) quindi non è un problema.

Quindi penso che sia a posto (ma vorrei dormire 29 secondi per ridurre un po 'di flessibilità).

+0

Non sono convinto della cosa 29 sec .. Amazon richiede 60 secondi tra alcune chiamate API. 'Thread.Sleep (60 * 1000)' restituisce ancora un errore che parla di un ritardo di 60 secondi in rari casi e quindi, in * quel * caso specifico, dormo per 62 secondi, cioè lo lascio * di più * lento. YMMV e tutto ciò .. –

1

Va bene, tranne che non è possibile interromperlo una volta che va in sospensione, senza interrompere il thread (che non è consigliato).

Ecco perché uno ManualResetEvent potrebbe essere un'idea migliore, poiché può essere segnalato ("risvegliato") da un thread diverso.

1

potresti attaccarti al metodo Thread.Sleep. Ma sarebbe più elegante programmare l'esecuzione ogni 30 minuti, quindi non dovrai occuparti dell'attesa all'interno della tua applicazione.

5

In generale, Thread.Sleep è come qualsiasi altro strumento: perfettamente OK da usare, tranne quando è terribilmente abusato. Non sono d'accordo con la parte "non in generale buona pratica", che è il risultato di abusi di persone su Thread.Sleep quando dovrebbero fare qualcos'altro (vale a dire il blocco su un oggetto di sincronizzazione).

Nel tuo caso il programma è single-threaded, non ha UI (cioè il thread non ha un loop di messaggi) e non vuoi sincronizzarti con eventi esterni. Pertanto Thread.Sleep va bene.

0

Thread.Sleep non è il migliore per l'esecuzione della logica periodica. Thread.Sleep (n) significa che il thread abbandonerà il controllo per n millisecondi. Non è garantito che riprenderà il controllo dopo n millisecondi, dipende dal carico della CPU.

0

Se si blocca il thread per 30 minuti caso è necessario pianificare un'attività di Windows ogni 30 minuti, in modo che il programma venga eseguito e quindi termini. In questo modo non stai bloccando un thread per così tanto tempo.

Per tempi più brevi, come 30 secondi/1 minuto, System.Thread.Sleep() è perfettamente a posto. Per più di 5 minuti vorrei usare un compito di Windows. (In spagnolo penso che nella versione inglese si chiami così, sto parlando delle attività che pianifichi dal pannello di controllo ;-))