我在我的类库中实现了缓存并遇到了问题。我所做的是,我传递一个我需要从XML文件中读取的值,它将返回节点和值。我使用字典将子节点存储为键值对。请参阅我的xml示例
<?xml version="1.0" encoding="utf-8"?>
<Settings>
<Test1>
<CompanyDetails>
<Name>Test1</Name>
<Address1>Add1</Address1>
<Address2>Add2</Address2>
<Address3>Add3</Address3>
<Phone>1111</Phone>
</CompanyDetails>
<Email>
<Contact>contact@test1.com</Contact>
</Email>
<AdminUsers>
<User1>user1</User1>
<User2>user2</User2>
</AdminUsers>
</Test1>
</Settings>
请参阅下面的代码
using System.Web;
public Dictionary<string, string> GetDataFromSettings(string strValues)
{
Dictionary<string, string> dictValus = new Dictionary<string, string>();
XmlDocument xmlDoc = new XmlDocument();
string xmlFilePath = "D:\\Test.xml";
xmlDoc.Load(xmlFilePath);
if (!(xmlDoc == null))
{
string[] splitValues = strValues.Split(new char[] { ',' });
if (splitValues.Length > 1)
{
Dictionary<string, string> strDictValues = new Dictionary<string, string>();
foreach (string strName in splitValues)
{
if (HttpRuntime.Cache[strName.Trim()] == null)
{
strDictValues.Clear();
XmlNodeList xmlList = xmlDoc.SelectNodes("Settings/Test1/" + strName.Trim());
foreach (XmlNode node in xmlList)
{
if (node.FirstChild.Name.ToString() != node.LastChild.Name.ToString())
{
foreach (XmlNode childNode in node.ChildNodes)
{
strDictValues.Add(strName.Trim() + "." + childNode.LocalName, childNode.InnerText);
}
}
else
{
strDictValues.Add(strName.Trim() + "." + node.FirstChild.LocalName, node.InnerText);
}
}
HttpRuntime.Cache.Insert(strName.Trim(), strDictValues,new System.Web.Caching.CacheDependency(xmlFilePath));
}
else
{
Dictionary<string, string> tmpDict = new Dictionary<string, string>();
tmpDict = (Dictionary<string, string>)HttpRuntime.Cache[strName.Trim()];
foreach (var tmpVal in tmpDict)
{
strDictValues.Add(tmpVal.Key, tmpVal.Value);
}
}
foreach (var tmpStrDict in strDictValues)
{
dictValus.Add(tmpStrDict.Key, tmpStrDict.Value);
}
}
}
}
return dictValus;
}
在我上面的xml示例中,我将字符串传递为&#34; CompanyDetails,Email&#34;到上面的函数,我拆分字符串,然后将每个字符串的值分别存储在缓存中。当我第一次运行时,&#34; CompanyDetails&#34;存储在名为&#34; CompanyDetails&#34;的缓存中。当它进入节点&#34;电子邮件&#34;时,缓存[&#34;公司详细信息&#34;]将被覆盖,并且还会创建缓存[&#34;电子邮件&#34;]并且它们都具有相同的价值观。这是不正确的。我无法找到它发生的原因。
谢谢,
Jollyguy
答案 0 :(得分:0)
问题在于,在构建缓存时,清除并重用字典而不是为每个strName
密钥创建新字典。由于您清除的字典是添加到缓存中的字典 - 不复制字典,但只保存对它的引用 - 您将清除以前的值。
尝试以下操作(注意我重构了一个稍低级别的版本以便于调试,并且消除了对&#34; strName.Trim()&#34;)的多余调用:
public Dictionary<string, string> GetDataFromSettings(TextReader reader, string xmlFilePath, string strValues)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
return GetDataFromSettings(xmlDoc, xmlFilePath, strValues);
}
public Dictionary<string, string> GetDataFromSettings(XmlDocument xmlDoc, string xmlFilePath, string strValues)
{
Dictionary<string, string> dictValus = new Dictionary<string, string>();
if (!(xmlDoc == null))
{
string[] splitValues = strValues.Split(new char[] { ',' });
if (splitValues.Length > 1)
{
foreach (string strName in splitValues.Select((s) => s.Trim()))
{
Dictionary<string, string> strDictValues = new Dictionary<string, string>();
if (HttpRuntime.Cache[strName] == null)
{
XmlNodeList xmlList = xmlDoc.SelectNodes("Settings/Test1/" + strName);
foreach (XmlNode node in xmlList)
{
if (node.FirstChild.Name.ToString() != node.LastChild.Name.ToString())
{
foreach (XmlNode childNode in node.ChildNodes)
{
strDictValues.Add(strName + "." + childNode.LocalName, childNode.InnerText);
}
}
else
{
strDictValues.Add(strName + "." + node.FirstChild.LocalName, node.InnerText);
}
}
HttpRuntime.Cache.Insert(strName, strDictValues, new System.Web.Caching.CacheDependency(xmlFilePath));
}
else
{
var tmpDict = (Dictionary<string, string>)HttpRuntime.Cache[strName];
foreach (var tmpVal in tmpDict)
{
strDictValues.Add(tmpVal.Key, tmpVal.Value);
}
}
foreach (var tmpStrDict in strDictValues)
{
dictValus.Add(tmpStrDict.Key, tmpStrDict.Value);
}
}
}
}
return dictValus;
}