В моем приложении C # / XAML metro есть кнопка, которая запускает длительный процесс. Итак, как рекомендовано, я использую 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, являются более сложными, и в разных точках выполнения могут потребоваться разные типы пользовательского ввода. Так что разбить логику на несколько методов было бы нетривиально.
ManualResetEvent(Slim)
, похоже, не поддерживаетWaitAsync()
.