在ASP.NET中更新Dictionary <T,U>的静态方法 - 在字典本身上锁定()是否安全?

Dyl*_*tie 5 c# asp.net locking thread-safety

我有一个类,它维护一个来自我的域控制器的缓存查找结果的静态字典 - 用户的给定名称和电子邮件.

我的代码看起来像:

private static Dictionary<string, string> emailCache = new Dictionary<string, string>();

protected string GetUserEmail(string accountName)
{
    if (emailCache.ContainsKey(accountName))
    {
        return(emailCache[accountName]);
    }

    lock(/* something */)
    {
        if (emailCache.ContainsKey(accountName))
        {
            return(emailCache[accountName]);
        }

        var email = GetEmailFromActiveDirectory(accountName);
        emailCache.Add(accountName, email);
        return(email);
    }
}
Run Code Online (Sandbox Code Playgroud)

需要锁吗?我假设是因为多个请求可能同时执行查找并最终尝试将相同的密钥插入到同一个静态字典中.

如果锁必需的,做我需要创建锁令牌使用一个专用的静态对象实例,或者是它的安全使用实际的词典实例作为锁定令牌?

Eli*_*xir 5

.NET中的集合不是线程安全的,因此确实需要锁定.使用字典的替代方法可以使用.NET 4.0中引入的并发字典

http://msdn.microsoft.com/en-us/library/dd287191.aspx


Jan*_*Jan 2

是的,只要其他线程上的代码可以/将访问静态对象,就需要锁。

是的,锁定字典本身是安全的,只要它不能通过公共 getter 访问即可。然后调用者可能会使用该对象来锁定自身,这可能会导致死锁。因此,如果您的字典有些公开,我建议使用单独的对象来锁定。