在我的C#/ XAML metro应用程序中,有一个按钮可以启动长时间运行的进程。因此,推荐,我使用异步/等待以确保UI线程不会被阻塞:是否有可能等待事件而不是另一个异步方法?
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'。使用“SemaphoreSlim”有没有优势?或者你可以使用其中一种吗? –
@DanielHilgarth'ManualResetEvent(Slim)'似乎不支持'WaitAsync()'。 – svick
@svick:好点。但是,由于'GetResult'已经是'async',所以你可以在这个方法中不会出现任何问题,不是吗? –