假设我有以下订阅事件的方法。事件发生时会调用回调。我想阻止我的方法返回,直到回调被调用,或者在 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()
的执行?
答案 0 :(得分:2)
看看这个:
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
来表示字符串何时被设置。
此时,我们等待 Task.WhenAny
,它让我们知道信号量何时释放或延迟任务结束。如果信号量释放,我们可以安全地假设字符串已经设置并返回。