首页 > 解决方案 > 等待在异步方法中调用回调

问题描述

假设我有以下订阅事件的方法。事件发生时调用回调。我想阻止我的方法返回,直到调用回调,或者经过 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()调用回调之前暂停执行?

标签: c#async-await

解决方案


看看这个:

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 发布,我们可以安全地假设字符串已设置并返回它。


推荐阅读