c# - 等待在异步方法中调用回调
问题描述
假设我有以下订阅事件的方法。事件发生时调用回调。我想阻止我的方法返回,直到调用回调,或者经过 10 秒。
public async Task<string> GetImportantString()
{
string importantResult = null;
await SubscribeToEvent("some event", async (message) =>
{
importantResult = message; // When "some event" happens, callback is called and we can set importantResult
}
return message; // Only return when the callback is called, or 10 seconds have passed
}
的签名SubscribeToEvent()
如下:
public Task SubscribeToEvent(string event, Action<string> handler);
我将使用方法GetImportantString()
的方式如下:
public void SomeMethod()
{
// Do some things
var importantString = await GetImportantString();
// Do other things
}
GetImportantString()
问题是在调用回调之前我找不到不返回的方法。理想情况下,我想等到回调调用最多 10 秒,如果在 10 秒内未调用回调,则返回错误。如何在GetImportantString()
调用回调之前暂停执行?
解决方案
看看这个:
public async Task<string> GetImportantString()
{
string importantResult = null;
using (var sph = new SemaphoreSlim(0, 1))
{
await SubscribeToEvent("some event", async (message) =>
{
importantResult = message; // When "some event" happens, callback is called and we can set importantResult
sph.Release();
});
var t = sph.WaitAsync();
if (await Task.WhenAny(t, Task.Delay(10000)) == t)
{
return importantResult;
}
}
throw new TimeoutException(); // whatever you want to do here
}
SemaphoreSlim
当字符串被设置时,我们使用 a来表示。
在那一点上,我们等待Task.WhenAny
它让我们知道信号量何时释放或延迟任务过去。如果 Semaphore 发布,我们可以安全地假设字符串已设置并返回它。
推荐阅读
- ruby-on-rails - 使用 Papertrail 的 attribute_name_was
- python - 在 Django 中将 JWT 与自定义用户模型一起使用时遇到问题
- javascript - 如何使用 JQuery 从 RSS 提要中提取图像?
- visual-studio - 在 IISExpress 上启动 localhost:远程设备或资源不接受连接
- android - 片段的新活动?
- node.js - 我想通过单击按钮向订阅我的网页的用户发送电子邮件
- php - PHP Composer Autoload 找不到类错误
- powerbi - 如何将来自两个查询的汇总数据加入 DAX Power BI 中的新表中
- javascript - Javascript - 简单的 OOP 封装
- sql - oracle选择数据集中没有返回的日期