0

HttpRuntime.Cache を使用して顧客のリストを 60 分間保存する WCF サービスがあります。

次のコマンドを実行すると、3 回目に文字列に「string3」が含まれるのはなぜですか

  string mykey = "mykey-1";
    List<string> strings = null;

    strings = HttpRuntime.Cache[mykey] as List<string>;

    if (strings == null)
    {
        strings = new List<string>();
        strings.Add("string1");
        strings.Add("string2");
        HttpRuntime.Cache[mykey] = strings;
    }
    else
    {
        strings.Add("string3");
    }

私は期待します:

1 回目: 文字列オブジェクトが null であるため、作成された「string1」と「string2」が追加され、キャッシュされました

2 回目: 文字列がキャッシュから取り出され、「string3」が追加されました

3 回目: 文字列はキャッシュから取り出されましたが、「string3」を再度追加する前に、既に取得されています。

共有メモリか、アプリケーション プール内の何かですか。キャッシュから引き出して変更すると、キャッシュされたバージョンが変更され、再追加す​​る必要がなくなります。

コードをもう一度実行すると、別の「string3」などを取得します

前もって感謝します

4

1 に答える 1

0

List<string>クラスは参照型です。これは、同じインスタンスを参照する複数の変数を持つことができることを意味します。変数の 1 つを使用して何かを変更すると、実際にはすべて同じオブジェクト/インスタンスを参照しているため、変更は他の変数を通じても表示されます。

サンプルでは、​​最初のリクエストで の新しいインスタンスを作成しList<string>、それにいくつかの文字列を追加してからキャッシュに追加します。したがって、最初のリクエストの後、HttpRuntime.Cacheオブジェクトは作成されたインスタンスへの参照を保持しますList<string>

2 番目の要求では、このインスタンスへの参照を変数に割り当てList<stringますstrings。そのstringsため、最初のリクエストで作成されたインスタンスを参照しています。またHttpRuntime.Cache、同じインスタンスへの参照も保持しています。次に、リストにもう 1 つの文字列を追加します。の 1 つのインスタンスがList<string>メモリ内で更新され、新しい文字列が含まれます。

3 回目の実行では、この同じインスタンスへの参照をもう一度strings変数にコピーします。これは、最初のリクエストで作成され、その後 2 番目のリクエストで変更されたものとまったく同じインスタンスを参照しています。したがって、この 3 番目のリクエストには、すでにstring3値が含まれています。aList<string>には同じ値を持つ複数の項目を問題なく含めることができるため、3 番目の要求は値 を持つ別の項目をリストに追加しますstring3。その後の追加のリクエストなど。

あなたが書いた

共有メモリか、アプリケーション プール内の何かですか。キャッシュから引き出して変更すると、キャッシュされたバージョンが変更され、再追加す​​る必要がなくなります。

あなたがそうするとき、あなたはstrings = HttpRuntime.Cache[mykey] as List<string>;実際にそれをキャッシュから引き出していません。むしろ、キャッシュで既に参照されているものへの参照を作成しています。

したがって、答えはイエスです。ローカル参照 (=strings変数) を介して行われた変更は、再追加せずにキャッシュに「保存」されます。

于 2013-03-22T13:46:13.867 に答える