Remplacement de Thread.Sleep dans .NET pour Windows Store

98

Thread.Sleep ne semble pas être pris en charge dans les applications .NET pour Windows Store.

Par exemple, ce

System.Threading.Thread.Sleep(1000);

compilera lors du ciblage de tout .NET Framework (2.0, 3.5, 4.0, 4.5), mais pas lors du ciblage de .NET pour les applications du Windows Store (ou dans une bibliothèque de classes portable qui cible à la fois 4.5 et store).

System.Threading.Thread est toujours là, il n'a tout simplement pas la méthode Sleep.

J'ai besoin de retarder quelque chose de quelques secondes dans mon application, existe-t-il un remplacement approprié?

MODIFIEZ pourquoi le délai est nécessaire: Mon application est un jeu et le délai consiste à donner l'impression que l'adversaire informatique "pense" à son prochain coup. La méthode est déjà appelée de manière asynchrone (le thread principal n'est pas bloqué), je veux juste ralentir le temps de réponse.

Max
la source
2
Étant donné que les applications du Windows Store ne sont pas censées pouvoir geler l'interface utilisateur (tout est censé être asynchrone), il est logique qu'elle ne soit pas prise en charge.
Sruly
2
Avez-vous des événements ou la Monitorclasse? Vous pouvez utiliser la Waitméthode avec un délai d'expiration pour simuler un sommeil.
Tudor
est-ce pour Apptivate.ms? : 3
EaterOfCode
3
Yay pour bannir Thread.Sleepà la poubelle de la mauvaise technologie.
dépenser le

Réponses:

203

Les applications du Windows Store adoptent l’asynchronie - et une «pause asynchrone» est fournie par Task.Delay. Donc, dans une méthode asynchrone, vous écririez:

await Task.Delay(TimeSpan.FromSeconds(30));

... ou quel que soit le délai souhaité. La méthode asynchrone continuera 30 secondes plus tard, mais le thread ne sera pas bloqué, comme pour toutes les awaitexpressions.

Jon Skeet
la source
1
Malheureusement, Task.Delay ne semble pas être pris en charge lorsque vous ciblez .NET 4.5 + store + WP7 dans une bibliothèque de classes portable. Je suppose que je vais devoir déplacer cela dans les classes spécifiques à la plate-forme.
Max
1
@Max: Non, car il n'existait pas avant .NET 4.5. IIRC, WP7 lui-même n'a aucun support TPL. (Je pourrais me tromper ...)
Jon Skeet
4
Vous pouvez virer .RunSynchronously()si nécessaire.
HappyNomad
1
@RAM: Well Thread.Sleep est pris en charge dans .NET 3.5, donc la question ne s'applique pas. Vous avez sans doute une question, mais il ne semble pas que ce soit la même chose que celle-ci. Veuillez lire tinyurl.com/stack-hints puis poser une nouvelle question.
Jon Skeet
2
@RAM: Je ne sais pas comment j'étais censé le deviner à partir de vos commentaires. Il y a déjà beaucoup de questions similaires sur SO concernant WPF et l'animation.
Jon Skeet
46

Je déteste énoncer l'évidence mais au cas où quelqu'un voudrait une seule ligne System.Threading.Tasks.Task.Delay(3000).Wait()

Antoine Thomas
la source
20

J'ai juste eu le même problème et j'ai trouvé une autre solution intéressante que je voulais partager avec vous. Si vous voulez vraiment bloquer le fil, je le ferais comme ça (merci @Brannon pour l'astuce "slim"):

// `waitHandle.Set` is never called, so we wait always until the timeout occurs
using (var waitHandle = new ManualResetEventSlim(initialState: false))
{
    waitHandle.Wait(TimeSpan.FromSeconds(5));
}
Johannes Egger
la source
C'est la meilleure réponse pour le codage portable.
zezba9000
Utilisez la version "mince" de ceci.
Brannon
11

MainPage.xaml.cs

public MainPage()
{
  this.InitializeComponent();
  this.WaitForFiveSeconds();
}

private async void WaitForFiveSeconds()
{
  await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(5));
  // do something after 5 seconds!
}
Benny Neugebauer
la source
-7

Il n'y a presque AUCUNE raison (sauf à des fins de test) de JAMAIS utiliser Thread.Sleep().

SI (et seulement si) vous avez une très bonne raison d'envoyer un thread en veille, vous voudrez peut-être vérifier Task.Delay(), ce que vous pouvez attendre pour "attendre" pendant un temps spécifié. Bien que ce ne soit jamais une bonne idée d'avoir un fil assis et de ne rien faire. Mauvaise pratique ...

igrimpe
la source
9
Je ne suis pas d'accord. Si le thread est un thread d'arrière-plan et que le sommeil est court, il est plus efficace de le mettre en veille pendant quelques millisecondes que d'utiliser un minuteur.
Jason Steele
1
et parfois on vous dit de le faire malgré avoir informé ladite figure d'autorité des conséquences;)
Jordanie