1

我在方法内部有以下代码:

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

4 回答 4

3

先说几点:

  1. 不要currency每次都初始化。当缓存已经包含一个实例时,这是浪费时间。
  2. 切勿尝试检查缓存中是否有某些内容,而是通过两个不同的步骤检索它。在这些步骤之间,缓存可能已经被另一个进程清除,创建一个NullReferenceException.
  3. 在您对问题的第一次编辑中,您将其他一些对象放入缓存中。在其他位置检查您的软件。如果代码Cache["Currency"]中的 ANYWHERE 填充了其他类型的对象,则as操作将始终返回null.

您的代码必须如下所示:

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;
        }
    }
}
于 2013-05-20T12:15:41.163 回答
0

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

Cache["Currency"] = currency;

代替:

Cache["Currency"] = someObject;

或者,如果您真的打算使用,请someObject确保它是类型,Dictionary<string, List<Currency>>否则as将返回null

编辑

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

HttpContext.Cache["Currency"] = currency;
于 2013-05-20T12:04:11.790 回答
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

于 2013-05-20T12:02:02.267 回答
0

您好尝试使用以下代码调试其他部分

else
{
  currrency = Cache["Currency"] ;
 //here I am getting null reference exception:
 foreach (var item in currency)
}
于 2013-05-20T12:18:16.003 回答