HttpContext.Current.Cache потокобезопасен? - PullRequest
11 голосов
/ 27 января 2011

Пожалуйста, проверьте код ниже:

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[];
}

Код, как вы можете заключить, в основном для кэширования некоторых значений для выпадающего списка на веб-странице.

Сначала он пытается прочитать объект 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)

Логически, никогда не должно быть случая, когда система пытается добавить ключ testDropDown в HashTable, когдаоно уже присутствует, первое условие else не должно допускать этого.

Единственное, что мне приходит в голову, - это возможность другого потока добавить ключ в HashTable в тот момент, когда проверка условия не удалась напервый поток, и он также пытается добавить ключ.

Насколько я знаю, Cache является потокобезопасным статическим объектом, но я не могу думать ни о чем другом, вызывающем эту ошибку.Ребята, не могли бы вы помочь мне определить причину здесь?

1 Ответ

21 голосов
/ 27 января 2011

Сам объект HttpContext.Current.Cache является поточно-ориентированным, что означает, что его хранение и чтение из него являются поточно-ориентированными, но, очевидно, объекты, которые вы храните внутри, могут быть не поточно-ориентированными. В вашем случае вы сохраняете Hashtable, который не является потокобезопасным объектом, что означает, что этот экземпляр потенциально может быть разделен между несколькими потоками, и может быть одновременное чтение и запись в хеш-таблицу, что может привести к проблемам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...