В моем приложении метро C # / XAML есть кнопка, запускающая длительный процесс. Итак, как рекомендовано, я использую async / await, чтобы убедиться, что поток пользовательского интерфейса не заблокирован:
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)
...
}
Иногда для продолжения работы, происходящей в GetResults, требуется дополнительный ввод пользователя. Для простоты предположим, что пользователю просто нужно нажать кнопку «продолжить».
У меня вопрос: как я могу приостановить выполнение GetResults таким образом, чтобы оно ожидало события, например, щелчка другой кнопки?
Вот уродливый способ добиться того, что я ищу: обработчик событий для кнопки "продолжить" устанавливает флаг ...
private bool _continue = false;
private void buttonContinue_Click(object sender, RoutedEventArgs e)
{
_continue = true;
}
... и GetResults периодически опрашивает его:
buttonContinue.Visibility = Visibility.Visible;
while (!_continue) await Task.Delay(100); // poll _continue every 100ms
buttonContinue.Visibility = Visibility.Collapsed;
Опрос явно ужасен (занятое ожидание / трата циклов), и я ищу что-то, основанное на событиях.
Любые идеи?
Кстати, в этом упрощенном примере одним из решений было бы, конечно, разделить GetResults () на две части, вызвать первую часть с помощью кнопки запуска и вторую часть с помощью кнопки продолжения. На самом деле, все, что происходит в GetResults, более сложное, и в разных точках выполнения могут потребоваться разные типы пользовательского ввода. Поэтому разбить логику на несколько методов было бы нетривиально.