当前位置: 首页 > 知识库问答 >
问题:

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

公英哲
2023-03-14

在我的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中发生的事情需要额外的用户输入才能继续。为了简单起见,假设用户只需单击“Continue”按钮。

我的问题是:如何挂起GetResults的执行,让它等待一个事件,比如单击另一个按钮?

这里有一个丑陋的方法来实现我所寻找的:Continue“按钮的事件处理程序设置了一个标志...

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()分成两部分,从start按钮调用第一部分,从continue按钮调用第二部分。实际上,GetResults中发生的事情更加复杂,在执行过程中的不同时刻可能需要不同类型的用户输入。因此,将逻辑分解为多个方法将不是一件小事。

共有1个答案

西门飞星
2023-03-14

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

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

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

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

或者,您可以使用TaskCompletionSource 类的实例来创建表示按钮单击结果的任务 :

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

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

// wait for task somewhere else
await tcs.Task;
 类似资料:
  • 问题内容: 我正在将JSHint用于JavaScript项目(带有Visual Studio Code)。在此项目中,我使用async / await,JSHint将其突出显示为错误。 我尝试设置jshint,但似乎“ esversion”的最大版本为6。 jshint支持异步/等待吗?如果可以,如何打开它?如果没有,是否有任何解决方法? 问题答案: 更新(2019年2月) :从2.10.1版本开

  • 问题内容: 是否可以在另一个CSS文件中包含一个CSS文件? 问题答案: 是: 注意: 该规则必须先于所有其他规则(除外)。 其他语句需要其他服务器请求。或者,将所有CSS连接到一个文件中,以避免多个HTTP请求。例如,复制的内容和入和仅供参考。

  • 我已经设置了这组重写(Zend Framework默认重写规则): 我的文件夹只包含和,没有其他内容。 重写规则应通过index.php将所有请求发送到不存在的文件。这适用于(无论是否存在控制器),但不适用于或以开头的任何其他url。 所有URL都被路由到apache的404页面,所有其他URL都可以工作。 我该如何解决这个问题?

  • 我试图利用es7异步功能,即。 在这里,所有promise*函数都进行ajax调用,并返回或如果ajax响应满足传递的参数,我相信我不能连续使用3个等待,因此需要一种方法来等待所有这些调用以某种方式返回它们的值。

  • 我正在安装,默认情况下我有路径来设置我的。如果我选择此选项,一些文件夹出现在路径上。 这些文件夹是: > .Android .oracle_jre_usage .Gradle 为了更干净一点,我尝试将所有这些文件夹包装到另一个文件夹中,但每次运行时,它都给了我重新配置设置的选项。如果再次配置它们,文件夹将重新出现在路径上。 编辑二:根据提供的移动文件夹的博客,我更改的默认设置: 这里有as服务目录

  • 问题内容: 如果一个同步方法调用另一个同步方法,那么线程安全吗? 问题答案: 是的,将方法标记为时,您实际上是在这样做: 当线程调用从method1进入method2时,它将确保它持有对的锁定,该锁定已经存在,然后可以通过。 当线程直接进入method1或method2时,它将阻塞直到获得锁(),然后进入。 正如詹姆斯·布莱克(James Black)在评论中指出的那样,您必须了解方法主体内部的操