缓存值被覆盖?

时间:2014-09-04 13:27:47

标签: c#

我在我的类库中实现了缓存并遇到了问题。我所做的是,我传递一个我需要从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

1 个答案:

答案 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;
    }