是否可以等待一个事件,而不是另一种异步方法? [英] Is it possible to await an event instead of another async method?

查看:173
本文介绍了是否可以等待一个事件,而不是另一种异步方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的C#/ XAML应用麦德龙,还有揭开序幕长期运行过程中的一个按钮。因此,建议,我使用异步/等待,以确保UI线程不会被阻塞:

In my C#/XAML metro app, there's a button which kicks off a long-running process. So, as recommended, I'm using async/await to make sure the UI thread doesn't get blocked:

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内发生的事情将需要额外的用户输入才能继续。为简单起见,假设用户只要有点击继续按钮。

Occasionally, the stuff happening within GetResults would require additional user input before it can continue. For simplicity, let's say the user just has to click a "continue" button.

我的问题是:我怎么可以暂停以这样的方式GetResults的执行,它等待一个的事件的如另一个按钮的点击

My question is: how can I suspend the execution of GetResults in such a way that it awaits an event such as the click of another button?

下面是一个丑陋的方式来实现我在寻找:在继续按钮,设置一个标志事件处理函数...

Here's an ugly way to achieve what I'm looking for: the event handler for the continue" button sets a flag...

private bool _continue = false;
private void buttonContinue_Click(object sender, RoutedEventArgs e)
{
    _continue = true;
}

...并GetResults定期轮询它:

... and GetResults periodically polls it:

 buttonContinue.Visibility = Visibility.Visible;
 while (!_continue) await Task.Delay(100);  // poll _continue every 100ms
 buttonContinue.Visibility = Visibility.Collapsed;

轮询显然是可怕的(忙循环等待/废物)和我正在寻找基于事件的一些东西。

The polling is clearly terrible (busy waiting / waste of cycles) and I'm looking for something event-based.

任何想法?

顺便说一下在该简化示例中,一种解决方案将是当然的分裂GetResults()分为两部分,调用第一部分从启动按钮和所述第二部分从继续按钮。在现实中,东西在GetResults发生的是更复杂的和不同类型的用户输入可以在执行中的不同点是需要的。所以,打破了逻辑分为多个方法是不平凡的。

Btw in this simplified example, one solution would be of course to split up GetResults() into two parts, invoke the first part from the start button and the second part from the continue button. In reality, the stuff happening in GetResults is more complex and different types of user input can be required at different points within the execution. So breaking up the logic into multiple methods would be non-trivial.

推荐答案

您可以使用 SemaphoreSlim类的一个信号:

You can use an instance of the SemaphoreSlim Class as a signal:

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

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

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


另外,您也可以使用 TaskCompletionSource&LT的实例; T>类创建任务< T> 那些重新presents结果按钮点击:


Alternatively, you can use an instance of the TaskCompletionSource<T> Class to create a Task<T> that represents the result of the button click:

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

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

// wait for task somewhere else
await tcs.Task;

这篇关于是否可以等待一个事件,而不是另一种异步方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆