Cache类问题的空引用

时间:2013-05-20 11:58:02

标签: c# caching nullreferenceexception

我在方法中有以下代码:

var currency = new Dictionary<string, List<Currency>>();

if (Cache["Currency"] == null)
{
    //here I fill currency with data and then set it to Cache.
    Cache["Currency"] = currency ;
}
else
{
     var currency = Cache["Currency"] as Dictionary<string, List<Currency>>;
     //here I am getting null reference exception:
     foreach (var item in currency)
}

我已经读过不应该直接在我的应用程序中使用Cache类, 但在我的情况下,正确使用Cache类是什么?

编辑: 我发布了所有代码:

 protected void DisplayCurrency()
{
    Dictionary<string, List<Currency>> currList = new Dictionary<string, List<Currency>>();

    if (Cache["Currency"] == null)
    {
        var xmlDoc = XElement.Load("http://www.tcmb.gov.tr/kurlar/today.xml");
        if (xmlDoc != null)
        {
            var queryXML = from xml in xmlDoc.Elements("Currency")
                           where (string)xml.Attribute("Kod") == "USD" || (string)xml.Attribute("Kod") == "EUR"
                           select xml;

            if (queryXML != null)
            {
                //fill Dictionary with data
                foreach (var item in queryXML)
                {
                    currList.Add(item.Attribute("Kod").Value, new List<Currency> 
                        {
                             new Currency 
                                 {     
                                     ForexBuying    = item.Element("ForexBuying").Value,
                                     ForexSelling   = item.Element("ForexSelling").Value, 
                                     BanknoteBuying = item.Element("BanknoteBuying").Value,
                                     BanknoteSelling= item.Element("BanknoteSelling").Value
                                 }
                        });
                }
                //Cache["Currency"] = currList;
                HttpContext.Current.Cache["Currency"] = currList;

                //read data from Dictionary instance
                foreach (var item in currList)
                {
                    switch (item.Key)
                    {
                        case "USD":
                            litUSDtxt.Text = item.Key;
                            foreach (var i in item.Value)
                            {
                                litUSD.Text = i.BanknoteSelling;
                            }
                            break;

                        case "EUR":
                            litEURtxt.Text = item.Key;
                            foreach (var i in item.Value)
                            {
                                litEUR.Text = i.BanknoteSelling;
                            }
                            break;
                    }
                }
            }
        }
        // Cache.Insert("Currency", currList, null, DateTime.Now.AddDays(1), TimeSpan.Zero);
    }
    else
    {
        var currency = Cache["Currency"] as Dictionary<string, List<Currency>>;
        foreach (var item in currency)
        {
            switch (item.Key)
            {
                case "USD":
                    litUSDtxt.Text = item.Key;
                    foreach (var i in item.Value)
                    {
                        litUSD.Text = i.BanknoteSelling;
                    }
                    break;

                case "EUR":
                    litEURtxt.Text = item.Key;
                    foreach (var i in item.Value)
                    {
                        litEUR.Text = i.BanknoteSelling;
                    }
                    break;
            }
        }
    }

}


class Currency
{
    public string ForexBuying { get; set; }
    public string ForexSelling { get; set; }
    public string BanknoteBuying { get; set; }
    public string BanknoteSelling { get; set; }
}

4 个答案:

答案 0 :(得分:3)

首先几点:

  1. 每次都不要初始化currency。当缓存已包含实例时,这是浪费时间。
  2. 永远不要尝试检查缓存中的某些内容,而不是在两个不同的步骤中检索它。在这些步骤之间,anohter进程可以清除缓存,创建NullReferenceException
  3. 在第一次编辑问题时,您将其他对象放入缓存中。在其他位置检查您的软件。如果您的代码Cache["Currency"]中的任何地方填充了anohter类型的对象,则as操作将始终返回null
  4. 您的代码必须如下所示:

    var currency = Cache["Currency"] as Dictionary<string, List<Currency>>;
    if (currency == null)
    {
        currency = new Dictionary<string, List<Currency>>();
        // At this point, initialize currency, fill it with data from your XML file, or whatever.
        Cache["Currency"] = currency;
    }
    // At this point, currency is loaded from cache or recreated. Now you can use it to fill your controls, variables, etc.
    

    或者......修改整个代码:

    protected void DisplayCurrency()
    {
        var currency = Cache["Currency"] as Dictionary<string, List<Currency>>;
    
        if (currency == null)
        {
            currency = new Dictionary<string,List<Currency>>();
            var xmlDoc = XElement.Load("http://www.tcmb.gov.tr/kurlar/today.xml");
            if (xmlDoc != null)
            {
                var queryXML = from xml in xmlDoc.Elements("Currency")
                               where (string)xml.Attribute("Kod") == "USD" || (string)xml.Attribute("Kod") == "EUR"
                               select xml;
    
                if (queryXML != null)
                {
                    //fill Dictionary with data
                    foreach (var item in queryXML)
                    {
                        currency.Add(item.Attribute("Kod").Value, new List<Currency> 
                        {
                             new Currency 
                             {     
                                 ForexBuying    = item.Element("ForexBuying").Value,
                                 ForexSelling   = item.Element("ForexSelling").Value, 
                                 BanknoteBuying = item.Element("BanknoteBuying").Value,
                                 BanknoteSelling= item.Element("BanknoteSelling").Value
                             }
                        });
                    }
                }
            }
            Cache["Currency"] = currency;
        }
        foreach (var item in currency)
        {
            switch (item.Key)
            {
                case "USD":
                    litUSDtxt.Text = item.Key;
                    foreach (var i in item.Value)
                    {
                        litUSD.Text = i.BanknoteSelling;
                    }
                    break;
    
                case "EUR":
                    litEURtxt.Text = item.Key;
                    foreach (var i in item.Value)
                    {
                        litEUR.Text = i.BanknoteSelling;
                    }
                    break;
            }
        }
    }
    

答案 1 :(得分:0)

var currency = Cache["Currency"] as Dictionary<string, List<Currency>>;

显然,强制转换失败,currency为空(如果无法进行转换,这是正确的行为)。您需要检查它是否为null

if (currency != null) {
    foreach(var item in currency) {

    }
}

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

答案 2 :(得分:0)

我认为你将它设置为错误的变量,不应该是:

Cache["Currency"] = currency;

而不是:

Cache["Currency"] = someObject;

如果您真的想要使用someObject,请确保其类型为Dictionary<string, List<Currency>>,否则as将返回null

修改

确保您使用HttpContext.Cache,这是一个常见问题:

HttpContext.Cache["Currency"] = currency;

答案 3 :(得分:0)

您尝试使用以下代码调试else部分

else
{
  currrency = Cache["Currency"] ;
 //here I am getting null reference exception:
 foreach (var item in currency)
}