.NET多线程访问共享登录会话

Way*_*neC 5 .net c# multithreading locking

我正在开发一个Web API应用程序,它通过API连接到后端系统.使用API​​的一个挑战是它需要维护一个远程会话,该会话在Web API的所有线程/请求之间共享.会话每隔几个小时到期,需要通过登录"刷新".

我当前实现的简化版本如下:

private static Object loginLock = new Object();

if(!Api.IsLoggedIn) 
{
    lock(loginLock)
    {
        if(!Api.IsLoggedIn)
        {
            Api.Login();
        }
    }
}

// Do stuff with the API
Run Code Online (Sandbox Code Playgroud)

在高并发负载下,当需要登录时,线程会在锁定时堆叠起来,并在成功登录时一次通过一个线程,这会导致性能瓶颈.

我正在寻找的是一种在需要登录时阻止所有线程的方法,但是在成功登录后让它们全部通过.

有没有更好的模式来解决这个问题?谷歌搜索似乎表明,ReaderWriterLockSlim或者Monitor Wait/Pulse/PulseAll可能是比标准锁更好的候选人.

Dam*_*ver 2

这是一个不寻常的问题,我不知道有任何内置内容专门解决这个问题。

请记住,我在几分钟内就把它搞定了,所以我绝对建议不要使用它,直到很多人有机会查看它并指出它的缺陷,这就是我的想法:

private Task _loginLock = null;

public void DoLoggedInCheck()
{
    if (!Api.IsLoggedIn)
    {
        var tcs = new TaskCompletionSource<int>();
        var tsk = tcs.Task;
        var result = Interlocked.CompareExchange(ref _loginLock, tsk, null);
        if (result == null)
        {
            if (!Api.IsLoggedIn)
            {
                Api.Login();
            }
            Interlocked.Exchange(ref _loginLock, null);
            tcs.SetResult(1);
        }
        else
        {
            result.Wait();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

逻辑是,在所有发现需要登录的线程中,它们都竞争(通过 )CompareExchange成为自愿解决问题的线程。其中一人获胜并完成任务,其余人则等待获胜者发出成功的信号。

这里仍然有少量的骚动,但应该很少见。