等待在异步方法中调用回调[重复]

问题描述 投票:0回答:1

假设我有以下订阅事件的方法。事件发生时会调用回调。我想阻止我的方法返回,直到调用回调或 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
1个回答
5
投票

看看这个:

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
,这让我们知道信号量何时释放或延迟任务何时结束。如果信号量释放,我们可以安全地假设字符串已被设置并返回它。

© www.soinside.com 2019 - 2024. All rights reserved.