En mi aplicación de metro C # / XAML, hay un botón que inicia un proceso de larga duración. Entonces, como se recomienda, estoy usando async / await para asegurarme de que el hilo de la interfaz de usuario no se bloquee:
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)
...
}
Ocasionalmente, las cosas que suceden dentro de GetResults requerirían una entrada adicional del usuario antes de poder continuar. Para simplificar, digamos que el usuario solo tiene que hacer clic en el botón "continuar".
Mi pregunta es: ¿cómo puedo suspender la ejecución de GetResults de tal manera que aguarde un evento como el clic de otro botón?
Aquí hay una forma fea de lograr lo que estoy buscando: el controlador de eventos para el botón continuar "establece una bandera ...
private bool _continue = false;
private void buttonContinue_Click(object sender, RoutedEventArgs e)
{
_continue = true;
}
... y GetResults lo sondea periódicamente:
buttonContinue.Visibility = Visibility.Visible;
while (!_continue) await Task.Delay(100); // poll _continue every 100ms
buttonContinue.Visibility = Visibility.Collapsed;
La encuesta es claramente terrible (espera ocupada / pérdida de ciclos) y estoy buscando algo basado en eventos.
¿Algunas ideas?
Por cierto, en este ejemplo simplificado, una solución sería dividir GetResults () en dos partes, invocar la primera parte desde el botón de inicio y la segunda parte desde el botón continuar. En realidad, las cosas que suceden en GetResults son más complejas y se pueden requerir diferentes tipos de entrada del usuario en diferentes puntos dentro de la ejecución. Por lo tanto, dividir la lógica en múltiples métodos no sería trivial.
ManualResetEvent(Slim)
no parece apoyarWaitAsync()
.