Dans mon application de métro C # / XAML, il y a un bouton qui lance un processus de longue durée. Donc, comme recommandé, j'utilise async / await pour m'assurer que le thread de l'interface utilisateur n'est pas bloqué:
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)
...
}
Parfois, les choses qui se produisent dans GetResults nécessiteraient une entrée utilisateur supplémentaire avant de pouvoir continuer. Pour plus de simplicité, disons que l'utilisateur n'a qu'à cliquer sur un bouton "Continuer".
Ma question est: comment puis-je suspendre l'exécution de GetResults de telle manière qu'elle attend un événement tel que le clic d'un autre bouton?
Voici une manière moche de réaliser ce que je recherche: le gestionnaire d'événements pour le bouton "Continuer" définit un drapeau ...
private bool _continue = false;
private void buttonContinue_Click(object sender, RoutedEventArgs e)
{
_continue = true;
}
... et GetResults l'interroge périodiquement:
buttonContinue.Visibility = Visibility.Visible;
while (!_continue) await Task.Delay(100); // poll _continue every 100ms
buttonContinue.Visibility = Visibility.Collapsed;
Le sondage est clairement terrible (attente chargée / perte de cycles) et je recherche quelque chose d'événementiel.
Des idées?
Btw dans cet exemple simplifié, une solution serait bien sûr de diviser GetResults () en deux parties, d'appeler la première partie à partir du bouton de démarrage et la deuxième partie à partir du bouton Continuer. En réalité, ce qui se passe dans GetResults est plus complexe et différents types d'entrée utilisateur peuvent être requis à différents moments de l'exécution. Donc, diviser la logique en plusieurs méthodes ne serait pas trivial.
ManualResetEvent(Slim)
ne semble pas soutenirWaitAsync()
.