在我的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',所以你可以在這個方法中不會出現任何問題,不是嗎? –