У моєму додатку метро C # / XAML є кнопка, яка починає тривалий процес. Тому, як рекомендується, я використовую async / очікую, щоб переконатися, що нитка інтерфейсу не блокується:
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()
.