Wymiana Thread.Sleep w .NET dla Windows Store

98

Wydaje się, że Thread.Sleep nie jest obsługiwany w .NET dla aplikacji ze Sklepu Windows.

Na przykład this

System.Threading.Thread.Sleep(1000);

będzie kompilować, gdy jest przeznaczony dla dowolnej platformy .NET Framework (2.0, 3.5, 4.0, 4.5), ale nie w przypadku .NET dla aplikacji ze Sklepu Windows (lub w przenośnej bibliotece klas, która jest przeznaczona zarówno dla wersji 4.5, jak i sklepu).

System.Threading.Thread nadal istnieje, po prostu nie ma metody Sleep.

Muszę opóźnić coś o kilka sekund w mojej aplikacji, czy jest odpowiedni zamiennik?

EDYTUJ, dlaczego opóźnienie jest potrzebne: Moja aplikacja jest grą, a opóźnienie ma sprawić, że wygląda na to, że komputerowy przeciwnik „myśli” o swoim następnym ruchu. Metoda jest już wywoływana asynchronicznie (główny wątek nie jest blokowany), chcę tylko spowolnić czas odpowiedzi.

Max
źródło
2
Biorąc pod uwagę, że aplikacje Windows Store nie powinny być w stanie zamrozić interfejsu użytkownika (wszystko ma być asynchroniczne), ma sens, że nie jest obsługiwane.
Lipiec
2
Czy masz wydarzenia lub Monitorzajęcia? Możesz użyć tej Waitmetody z limitem czasu, aby symulować sen.
Tudor
jest to dla Apptivate.ms? : 3
EaterOfCode
3
Brawo za wyrzucenie Thread.Sleepdo śmietnika złej technologii.
spender

Odpowiedzi:

203

Aplikacje ze Sklepu Windows obsługują asynchroniczność - a „asynchroniczna pauza” jest zapewniana przez Task.Delay. Więc w ramach metody asynchronicznej napisałbyś:

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

... lub jakiekolwiek opóźnienie, które chcesz. Metoda asynchroniczna będzie kontynuowana 30 sekund później, ale wątek nie zostanie zablokowany, tak jak w przypadku wszystkich awaitwyrażeń.

Jon Skeet
źródło
1
Niestety, Task.Delay nie wydaje się być obsługiwany, gdy celujemy w .NET 4.5 + store + WP7 w przenośnej bibliotece klas .. Myślę, że muszę to przenieść do klas specyficznych dla platformy.
Max
1
@Max: Nie, ponieważ nie istniał przed .NET 4.5. IIRC, sam WP7 nie ma żadnego wsparcia dla TPL. (Mogę się mylić ...)
Jon Skeet
4
W .RunSynchronously()razie potrzeby możesz przypiąć .
HappyNomad
1
@RAM: Cóż, Thread.Sleep jest obsługiwany w .NET 3.5, więc pytanie nie ma zastosowania. Bez wątpienia masz to pytanie, ale nie wygląda to tak samo, jak ten. Przeczytajcie tinyurl.com/stack-hints, a następnie zadajcie nowe pytanie.
Jon Skeet
2
@RAM: Nie jestem pewien, jak miałem to odgadnąć z twoich komentarzy. W SO jest już wiele podobnych pytań dotyczących WPF i animacji.
Jon Skeet
46

Nienawidzę mówić tego, co oczywiste, ale na wypadek, gdyby ktoś chciał jednego wiersza System.Threading.Tasks.Task.Delay(3000).Wait()

Antony Thomas
źródło
20

Po prostu miałem ten sam problem i znalazłem inne interesujące rozwiązanie, którym chciałem się z tobą podzielić. Jeśli naprawdę chcesz zablokować wątek, zrobiłbym to w ten sposób (dzięki @Brannon za "szczupłą" wskazówkę):

// `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
źródło
To najlepsza odpowiedź na przenośne kodowanie.
zezba9000
Użyj „smukłej” wersji tego.
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
źródło
-7

Nie ma prawie ŻADNEGO powodu (z wyjątkiem celów testowych), aby NIGDY używać Thread.Sleep().

JEŚLI (i tylko jeśli) masz bardzo dobry powód, aby wysłać wątek do uśpienia, możesz sprawdzić Task.Delay(), na który możesz poczekać, aby „poczekać” przez określony czas. Chociaż to nigdy nie jest dobry pomysł, żeby siedzieć i nic nie robić. Zła praktyka ...

igrimpe
źródło
9
Nie zgadzam się. Jeśli wątek jest wątkiem w tle, a sen jest krótki, bardziej wydajne jest uśpienie go na kilka milisekund niż użycie timera.
Jason Steele
1
a czasem każe ci to robić pomimo poinformowania wspomnianego autorytetu o konsekwencjach;)
Jordan