Sostituzione Thread.Sleep in .NET per Windows Store


98

Thread.Sleep non sembra essere supportato in .NET per le app di Windows Store.

Ad esempio, questo

System.Threading.Thread.Sleep(1000);

verrà compilato quando si targetizza qualsiasi .NET Framework (2.0, 3.5, 4.0, 4.5), ma non quando si rivolge a .NET per le app di Windows Store (o in una libreria di classi portabile che ha come target sia 4.5 che store).

System.Threading.Thread è ancora lì, semplicemente non ha il metodo Sleep.

Devo ritardare qualcosa di alcuni secondi nella mia app, esiste un sostituto adatto?

EDIT perché è necessario il ritardo: la mia app è un gioco e il ritardo serve a far sembrare che l'avversario del computer stia "pensando" alla sua prossima mossa. Il metodo è già chiamato in modo asincrono (il thread principale non è bloccato), voglio solo rallentare il tempo di risposta.


2
Considerando che le app di Windows Store non dovrebbero essere in grado di bloccare l'interfaccia utente (tutto dovrebbe essere asincrono), ha senso che non sia supportata.
Sruly

2
Hai eventi o la Monitorclasse? È possibile utilizzare il Waitmetodo con un timeout per simulare un sonno.
Tudor

è questo per Apptivate.ms? : 3
EaterOfCode

3
Yay per essere bandito Thread.Sleepnella pattumiera della cattiva tecnologia.
spender

Risposte:


203

Le app di Windows Store adottano l'asincronia e una "pausa asincrona" è fornita da Task.Delay. Quindi all'interno di un metodo asincrono, dovresti scrivere:

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

... o qualunque ritardo tu voglia. Il metodo asincrono continuerà 30 secondi dopo, ma il thread non verrà bloccato, proprio come per tutte le awaitespressioni.


1
Sfortunatamente, Task.Delay non sembra essere supportato quando si mira a .NET 4.5 + store + WP7 in una libreria di classi portabile .. Immagino che dovrò spostarlo nelle classi specifiche della piattaforma.
Max

1
@ Max: No, perché non esisteva prima di .NET 4.5. IIRC, lo stesso WP7 non ha alcun supporto TPL. (Potrei sbagliarmi ...)
Jon Skeet

4
Puoi attaccare .RunSynchronously()se necessario.
HappyNomad

1
@RAM: Well Thread.Sleep è supportato in .NET 3.5, quindi la domanda non è applicabile. Senza dubbio hai una domanda, ma non sembra essere la stessa di questa. Si prega di leggere tinyurl.com/stack-hints quindi fare una nuova domanda.
Jon Skeet

2
@RAM: Non sono sicuro di come avrei dovuto immaginarlo dai tuoi commenti. Ci sono già molte domande simili su SO su WPF e animazione.
Jon Skeet

46

Odio affermare l'ovvio, ma nel caso qualcuno volesse una sola riga System.Threading.Tasks.Task.Delay(3000).Wait()


20

Ho appena avuto lo stesso problema e ho trovato un'altra soluzione interessante che volevo condividere con te. Se vuoi davvero bloccare il thread, lo farei in questo modo (grazie @Brannon per il suggerimento "sottile"):

// `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));
}

Questa è la migliore risposta per la codifica portatile.
zezba9000

Usa la versione "slim" di questo.
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!
}

-7

Non c'è quasi NESSUN motivo (tranne che per scopi di test) per usarlo MAI Thread.Sleep().

SE (e solo se) hai un'ottima ragione per mandare un thread a dormire, potresti voler controllare Task.Delay(), che puoi aspettare per "aspettare" per un tempo specificato. Anche se non è mai una buona idea avere un filo intorno e non fare nulla. Cattiva pratica ...


9
Non sono d'accordo. Se il thread è un thread in background e la sospensione è breve, è più efficiente farlo dormire per alcuni millisecondi rispetto all'utilizzo di un timer.
Jason Steele

1
ea volte ti viene detto di farlo nonostante tu abbia avvertito la suddetta figura autoritaria delle conseguenze;)
Jordan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.