Comment obtenir Thread.Sleep en attente?

139

J'écris une application liée au réseau basée sur le paradigme d'attente / sommeil.

Parfois, des erreurs de connexion se produisent, et d'après mon expérience, il vaut la peine d'attendre un certain temps, puis de réessayer l'opération.

Le problème est que si j'utilise Thread.Sleep ou une autre opération de blocage similaire dans await / async, cela bloque toute activité dans le thread de l'appelant.

Par quoi dois-je remplacer Thread.Sleep (10000) pour obtenir le même effet que

await Thread.SleepAsync(10000)

?

METTRE À JOUR

Je préférerai une réponse qui fait cela sans créer de fil supplémentaire

Arsen Zahray
la source

Réponses:

323

Les autres réponses suggérant de démarrer un nouveau fil sont une mauvaise idée - il n'est pas du tout nécessaire de le faire. Une partie du but de async/ awaitest de réduire le nombre de threads dont votre application a besoin.

Vous devriez plutôt utiliser Task.Delayce qui ne nécessite pas de nouveau thread, et a été conçu précisément à cet effet:

// Execution of the async method will continue one second later, but without
// blocking.
await Task.Delay(1000);
Jon Skeet
la source
Je suis toujours aux prises avec les trucs a4.5. Où est la branche d'exécution sur le code après cette instruction? La partie non dormante / bloquante l'exécute-t-elle ou le «thread» qui attend? L'exécution principale non bloquante laisse-t-elle simplement le bloc suivant (aka return)?
kenny
1
Ouais. C'est exactement ce dont j'ai besoin
Arsen Zahray
1
@kenny: Vous trouverez peut-être mon asyncintro utile. Lorsque l'attendable retourné par Task.Delayest awaited, puisqu'il n'est pas complet, la méthode courante renvoie une tâche incomplète. Plus tard, lorsque le se Delaytermine (hors d'une minuterie, pas d'un thread), le reste de la méthode est planifié pour s'exécuter. La suite se déroule dans un "contexte" qui peut revenir au même fil d'origine - détails sur mon blog.
Stephen Cleary
@StephenCleary merci pour cela. Alors ai-je raison de dire que le code après attendre est «programmé» pour l'exécution et le thread appelant revient?
kenny
2
Oui, le thread appelant retourne (immédiatement) et le code après le awaitest planifié (éventuellement).
Stephen Cleary