c# – 是否可以等待事件而不是另一个异步方法?

在我的C#/ XAML metro应用程序,有一个按钮,启动一个长期运行的过程。所以,按照推荐,我使用async / await,以确保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中发生的事情更复杂,并且在执行中的不同点可能需要不同类型的用户输入。所以将逻辑分解成多个方法将是不平凡的。

您可以使用SemaphoreSlim Class的实例作为信号:

private SemaphoreSlim signal = new SemaphoreSlim(0, 1);

// set signal in event
signal.Release();

// wait for signal somewhere else
await signal.WaitAsync();

或者,您可以使用TaskCompletionSource<T> Class的实例来创建表示按钮单击结果的Task<T>

private TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();

// complete task in event
tcs.SetResult(true);

// wait for task somewhere else
await tcs.Task;
http://stackoverflow.com/questions/12858501/is-it-possible-to-await-an-event-instead-of-another-async-method

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c# – 是否可以等待事件而不是另一个异步方法?