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可能是比标准锁更好的候选人.
这是一个不寻常的问题,我不知道有任何内置内容专门解决这个问题。
请记住,我在几分钟内就把它搞定了,所以我绝对建议不要使用它,直到很多人有机会查看它并指出它的缺陷,这就是我的想法:
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成为自愿解决问题的线程。其中一人获胜并完成任务,其余人则等待获胜者发出成功的信号。
这里仍然有少量的骚动,但应该很少见。
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |