In meiner C # / XAML-U-Bahn-App gibt es eine Schaltfläche, die einen lang laufenden Prozess startet. Wie empfohlen verwende ich async / await, um sicherzustellen, dass der UI-Thread nicht blockiert wird:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
await GetResults();
}
private async Task GetResults()
{
// Do lot of complex stuff that takes a long time
// (e.g. contact some web services)
...
}
Gelegentlich erfordern die Vorgänge in GetResults zusätzliche Benutzereingaben, bevor sie fortgesetzt werden können. Nehmen wir zur Vereinfachung an, der Benutzer muss nur auf die Schaltfläche "Weiter" klicken.
Meine Frage ist: Wie kann ich die Ausführung von GetResults so aussetzen, dass sie auf ein Ereignis wie das Klicken einer anderen Schaltfläche wartet ?
Hier ist ein hässlicher Weg, um das zu erreichen, wonach ich suche: Der Event-Handler für die Schaltfläche "Weiter" setzt ein Flag ...
private bool _continue = false;
private void buttonContinue_Click(object sender, RoutedEventArgs e)
{
_continue = true;
}
... und GetResults fragt es regelmäßig ab:
buttonContinue.Visibility = Visibility.Visible;
while (!_continue) await Task.Delay(100); // poll _continue every 100ms
buttonContinue.Visibility = Visibility.Collapsed;
Die Umfrage ist eindeutig schrecklich (beschäftigtes Warten / Verschwendung von Zyklen) und ich suche etwas Ereignisbasiertes.
Irgendwelche Ideen?
Übrigens wäre in diesem vereinfachten Beispiel eine Lösung natürlich, GetResults () in zwei Teile aufzuteilen, den ersten Teil über die Schaltfläche Start und den zweiten Teil über die Schaltfläche Weiter aufzurufen. In der Realität ist das Geschehen in GetResults komplexer und an verschiedenen Punkten der Ausführung können unterschiedliche Arten von Benutzereingaben erforderlich sein. Eine Aufteilung der Logik in mehrere Methoden wäre also nicht trivial.
ManualResetEvent(Slim)
scheint nicht zu unterstützenWaitAsync()
.