假设我有以下订阅事件的方法。事件发生时会调用回调。我想阻止我的方法返回,直到调用回调或 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", (message) =>
{
importantResult = message; // When "some event" happens, callback is called and we can set importantResult
try
{
sph.Release();
}
catch (ObjectDisposedException){}
});
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
,这让我们知道信号量何时释放或延迟任务何时结束。如果信号量释放,我们可以安全地假设字符串已被设置并返回它。