是否可以忽略finally块中的信号量释放?

时间:2019-03-27 15:36:13

标签: c# .net asynchronous semaphore

我有一种初始化某些对象的内存中缓存的方法,该方法在进入所述缓存之前被调用。据我所知,我正确地使用了SemaphoreSlim,但仍然多次锁定了信号灯,并且没有线程能够访问该块。有什么办法可以忽略finally块中的锁定释放?我们正在使用.NET 4.6.2,ASP.NET MVC并将其作为Azure应用程序托管。

private static readonly SemaphoreSlim _lock = new SemaphoreSlim(1);

private static async Task<bool> InitializeCache()
{
    if (Cache != null) return true;

    if (await _lock.WaitAsync(30000))
    {
        try
        {
            if (Cache != null) return true;

            var items = await API.GetKeysFromAPI();
            Cache = new ConcurrentDictionary<string, SamlSessionState>(items);

            return true;
        }
        catch (Exception e)
        {
            throw new Exception("Error initializing the cache", e);
        }
        finally
        {
            _lock.Release();
        }
    }
    else
    {
        // This keeps getting called after the semaphore locks up.
        throw new Exception("Error initializing the cache, the semaphore timed out."); 
    }
}

我希望finally块每次都会被调用。终止请求是否可以停止执行,以至于永远不会调用finally块?

2 个答案:

答案 0 :(得分:0)

this question上的“长答案”注释中所述,是的,在某些极端情况下,您的finally块可能不会执行。相同的问题还有更多的答案值得检查。

答案 1 :(得分:0)

如以上答案以及Microsoft Documentation所述,在某些极端情况下,可以跳过finally块。但是,我真的怀疑这是您的问题所在。这似乎是一个简单的死锁,在您的代码中的某个地方引起了。使用您的应用程序转储来进一步分析它,或者尝试使用一些日志记录语句查找死锁!