需要帮助理解ASP.NET中的锁定

时间:2014-09-19 08:33:40

标签: c# asp.net .net multithreading locking

我在理解锁定多用户/ 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;

有人知道我最能解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

答案1: 克服它并与重复的条目一起生活。

答案2: 如果启用了会话,则可以通过访问会话存储来获得来自同一用户(会话)的请求之间的隐式锁定。只需添加一个虚拟

Session["TRIGGER_SESSION_LOCKING_DUMMY"] = true

答案3: 对由Identity标记的对象实施一些自定义锁定。像这样的东西

lock(threadSafeStaticDictionary[User.Identity.Name]) { ... }

答案4: 直接锁定Identity对象(由于您获得重复,应该共享)(尽管不建议使用)

lock(User.Identity)