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. キャッシュに何かがあるかどうかを確認してから、2 つの異なる手順で取得しようとしないでください。これらのステップの間に、別のプロセスによってキャッシュがクリアされ、NullReferenceException.
  3. 質問の最初の編集で、キャッシュ内に他のオブジェクトを配置しました。別の場所でソフトウェアを確認してください。コード内の ANYWHERECache["Currency"]が別の型のオブジェクトで満たされている場合、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
var currency = Cache["Currency"] as Dictionary<string, List<Currency>>;

キャストが失敗し、currencynull であることは明らかです (これは、変換が不可能な場合の正しい動作です)。次のようになっているかどうかを確認する必要があります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

間違った変数に設定していると思いますが、そうではありません:

Cache["Currency"] = currency;

それ以外の:

Cache["Currency"] = someObject;

または、本当に使用するつもりの場合は、それがsomeObjectタイプであることを確認してください。Dictionary<string, List<Currency>>asnull

編集

を使用していることを確認してください。HttpContext.Cacheこれは一般的な問題です。

HttpContext.Cache["Currency"] = currency;
于 2013-05-20T12:04:11.790 に答える
0

こんにちは、次のコードでelse部分をデバッグしてみてください

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