Thread.Sleep-Ersatz in .NET für Windows Store

98

Thread.Sleep scheint in .NET für Windows Store-Apps nicht unterstützt zu werden.

Zum Beispiel dies

System.Threading.Thread.Sleep(1000);

Kompiliert beim Targeting von .NET Framework (2.0, 3.5, 4.0, 4.5), jedoch nicht beim Targeting von .NET für Windows Store-Apps (oder in einer tragbaren Klassenbibliothek, die sowohl auf 4.5 als auch auf Store abzielt).

System.Threading.Thread ist immer noch vorhanden, es gibt nur nicht die Sleep-Methode.

Ich muss etwas in meiner App um einige Sekunden verzögern. Gibt es einen geeigneten Ersatz?

BEARBEITEN Sie, warum die Verzögerung benötigt wird: Meine App ist ein Spiel und die Verzögerung soll es so aussehen lassen, als würde der Computergegner über seinen nächsten Zug "nachdenken". Die Methode wird bereits asynchron aufgerufen (Hauptthread ist nicht blockiert), ich möchte nur die Antwortzeit verlangsamen.

Max
quelle
2
Angesichts der Tatsache, dass Windows Store-Apps die Benutzeroberfläche nicht einfrieren können sollen (alles soll asynchron sein), ist es sinnvoll, dass sie nicht unterstützt wird.
28.
2
Hast du Events oder die MonitorKlasse? Sie können die WaitMethode mit einer Zeitüberschreitung verwenden, um einen Schlaf zu simulieren.
Tudor
ist das für Apptivate.ms? : 3
EaterOfCode
3
Yay für das Verbannen Thread.Sleepin den Mülleimer der schlechten Technik.
Spender

Antworten:

203

Windows Store-Apps unterstützen Asynchronität - und eine "asynchrone Pause" wird von bereitgestellt Task.Delay. Innerhalb einer asynchronen Methode würden Sie also schreiben:

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

... oder was auch immer Sie wollen. Die asynchrone Methode wird 30 Sekunden später fortgesetzt, aber der Thread wird nicht wie bei allen awaitAusdrücken blockiert .

Jon Skeet
quelle
1
Leider scheint Task.Delay beim Targeting von .NET 4.5 + store + WP7 in einer portablen Klassenbibliothek nicht unterstützt zu werden. Ich denke, ich muss dies in die plattformspezifischen Klassen verschieben.
Max
1
@ Max: Nein, da es vor .NET 4.5 nicht existierte. IIRC, WP7 selbst hat keine TPL-Unterstützung. (Ich könnte mich irren ...)
Jon Skeet
4
Sie können .RunSynchronously()bei Bedarf anheften .
HappyNomad
1
@RAM: Gut Thread.Sleep wird in .NET 3.5 unterstützt, daher trifft die Frage nicht zu. Zweifellos haben Sie eine Frage, aber es hört sich nicht so an, als wäre es dieselbe wie diese. Bitte lesen Sie tinyurl.com/stack-hints und stellen Sie eine neue Frage.
Jon Skeet
2
@ Ram: Ich bin mir nicht sicher, wie ich das aus deinen Kommentaren erraten sollte. Es gibt bereits viele ähnliche Fragen zu WPF und Animation zu SO.
Jon Skeet
46

Ich hasse es, das Offensichtliche zu sagen, aber falls jemand eine einzige Zeile wollte System.Threading.Tasks.Task.Delay(3000).Wait()

Antony Thomas
quelle
20

Ich hatte gerade das gleiche Problem und fand eine andere interessante Lösung, die ich mit Ihnen teilen wollte. Wenn du den Thread wirklich blockieren willst, würde ich es so machen (danke @Brannon für den "schlanken" Hinweis):

// `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
quelle
Dies ist die beste Antwort für tragbare Codierung.
zezba9000
Verwenden Sie die "schlanke" Version davon.
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
quelle
-7

Es gibt fast keinen Grund (außer zu Testzwecken) für die Verwendung Thread.Sleep().

WENN (und nur wenn) Sie einen sehr guten Grund haben, einen Thread in den Ruhezustand zu versenden, möchten Sie möglicherweise überprüfen Task.Delay(), auf welchen Sie warten können, um eine bestimmte Zeit zu "warten". Obwohl es nie eine gute Idee ist, einen Faden herumzusitzen und nichts zu tun. Schlechte Praxis ...

igrimpe
quelle
9
Ich bin nicht einverstanden. Wenn der Thread ein Hintergrund-Thread ist und der Ruhezustand kurz ist, ist es effizienter, ihn einige Millisekunden lang schlafen zu lassen, als einen Timer zu verwenden.
Jason Steele
1
und manchmal wird dir gesagt, dass du es tun sollst, obwohl du die Autoritätsperson über die Konsequenzen
Jordanien