我在理解锁定多用户/ Web应用程序的基本概念时遇到了一些麻烦。 当用户获得我们联合会的授权后,他将返回一个用户名声明,然后我们会用它来检索有关他的一些额外信息:
var claimsIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;
if(!claimsIdentity.HasClaim(CustomClaims.UserId)) //If not set, retrieve it from dataBase
{
//This can take some time
var userId = retrieveUserId(claimsIdentity.FindFirst(ClaimTypes.NameIdentifier));
//Because the previous call could take some time, it's possible we add the claim multiple time during concurrent requests
claimsIdentity.AddClaim(new Claim(CustomClaims.UserId, userId));
}
如代码中所示,重复索赔并不是我真正想要的,所以我想我会在检查周围锁定一切是否存在索赔:
private static readonly object _authorizeLock = new object();
...
lock(_authorizeLock)
{
if(!claimsIdentity.HasClaim(CustomClaims.UserId)) //If not set, retrieve it from dataBase
{
...
}
}
但是,这感觉不对。这个锁定不会用于所有传入请求吗?这意味着即使已经检索到他们的信息,即使授权用户仍然必须等待#34;
有人知道我最能解决这个问题吗?
答案 0 :(得分:0)
答案1: 克服它并与重复的条目一起生活。
答案2: 如果启用了会话,则可以通过访问会话存储来获得来自同一用户(会话)的请求之间的隐式锁定。只需添加一个虚拟
Session["TRIGGER_SESSION_LOCKING_DUMMY"] = true
答案3: 对由Identity标记的对象实施一些自定义锁定。像这样的东西
lock(threadSafeStaticDictionary[User.Identity.Name]) { ... }
答案4: 直接锁定Identity对象(由于您获得重复,应该共享)(尽管不建议使用)
lock(User.Identity)