请检查以下代码:
objDDLTable = HttpContext.Current.Cache["TestSet"] as Hashtable;
if (objDDLTable == null)
{
objDDLTable = new Hashtable();
arrDDLItems = GetDropDownList("testDropDown");
objDDLTable.Add("testDropDown", arrDDLItems);
HttpContext.Current.Cache["TestSet"] = objDDLTable;
}
else if (objDDLTable != null && !objDDLTable.Contains("testDropDown"))
{
arrDDLItems = GetDropDownList("testDropDown");
objDDLTable.Add("testDropDown", arrDDLItems);
HttpContext.Current.Cache["TestSet"] = objDDLTable;
}
else
{
arrDDLItems = objDDLTable["testDropDown"] as DdlItem[];
}
Run Code Online (Sandbox Code Playgroud)
您可以推断,代码基本上是为网页上的下拉列表缓存一些值.
首先,它尝试从缓存中读取HashTable对象,然后检查从缓存中读取的HashTable对象中是否存在特定键.如果是,则读取值(项目数组),否则,它从源读取数组并在HashTable中添加新密钥,然后将其存储回缓存以供后续使用.
这在大多数情况下都可以正常工作,但是,我们偶尔会遇到以下错误:
System.ArgumentException: Item has already been added.
Key in dictionary: 'testDropDown' Key being added: 'testDropDown' at
System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at
System.Collections.Hashtable.Add(Object key, Object value)
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,系统testDropDown在HashTable已经存在的情况下尝试在HashTable中添加密钥时应该永远不会出现这种情况,第一个其他条件不应该允许它.
我唯一想到的是另一个线程的可能性,当第一个线程上的条件检查失败时,另一个线程将键添加到HashTable,并且它还尝试添加密钥.
据我所知,Cache是一个线程安全的静态对象,但我想不出任何其他导致该错误.你能帮助我找出原因吗?
Dar*_*rov 21
该HttpContext.Current.Cache对象本身是线程安全的含义存储和从中读取是线程安全的,但很明显的对象,你店内可能不是线程安全的.在您的情况下,您正在存储一个Hashtable非线程安全对象,这意味着此实例可能在多个线程之间共享,并且可能会对哈希表进行并发读取和写入,这可能会导致问题.