System.Runtime.Caching.MemoryCacheとHttpRuntime.Cache-違いはありますか?


84

いずれかの間に違いがある場合、私は思ったんだけどMemoryCacheHttpRuntime.Cache1はASP.NET MVCプロジェクトで好まれ、?

私の知る限り、どちらもスレッドセーフであり、APIは一見同じですが、どちらを使用するかには違いがありますか?

回答:


80

HttpRuntime.CacheCache現在のアプリケーションのを取得します。

このMemoryCacheクラスはASP.NETCacheクラスに似ています。

このMemoryCacheクラスには、ASP.NETCacheクラスを使用したことがある場合によく知られている、キャッシュにアクセスするための多くのプロパティとメソッドがあります。

主な違いHttpRuntime.Cacheとは、MemoryCache後者は、ASP.NETアプリケーションではない.NET Frameworkアプリケーションによってそれが使用できるように変更されたことです。

追加の読み物について:

更新:

ユーザーからのフィードバックによると、Jon davisブログが機能しないことがあるので、記事全体を画像として掲載しましたので、ご覧ください。

注:はっきりしない場合は、画像をクリックしてください。その後、ブラウザで開きます。もう一度クリックしてズームします:)

ここに画像の説明を入力してください


そのジョンデイビスの記事は本当によく読まれています-一箇所で明確な長所と短所。
giedrius 2012

絶対にすべてが1か所にあります。良いものです。さらに、Davisは4つの異なるキャッシュ方法についても言及しました。
サンパス2012

2
@Spikehそれは私にとっては問題なくロードされています。
user247702 2014年

1
@Stijnありがとう、先日ロードしていませんでしたが、今戻ってきました:)
Spikeh 2014年

1
@sampathそれは今動作します。昨日はサイトがハッキングされたように見えました。ご協力いただきありがとうございます!
バガ2016年

24

これがJonDavisの記事です。読みやすさを維持するために、現在は廃止されているEntLibセクション、イントロ、および結論を切り取っています。


ASP.NETキャッシュ

ASP.NET、またはSystem.Web.dllアセンブリには、キャッシュメカニズムがあります。Webコンテキストの外部で使用することを意図したものではありませんが、Webの外部で使用することはでき、ある種のハッシュテーブルで上記のすべての有効期限動作を実行します。

Googleを精査した後、.NETの組み込みキャッシュ機能について議論したかなりの数の人々が、非WebプロジェクトでASP.NETキャッシュを使用することに頼ったようです。これは、.NETで最も利用可能で、最もサポートされている組み込みキャッシュシステムではなくなりました。.NET 4にはObjectCacheがありますが、これについては後で説明します。Microsoftは、ASP.NETキャッシュがWebの外部での使用を目的としていないことを常に断固として主張してきました。しかし、多くの人々はまだ.NET2.0と.NET3.5で立ち往生しており、何かを操作する必要があります。MSDNが明確に述べているにもかかわらず、これは多くの人々にとってうまくいきます。

注:Cacheクラスは、ASP.NETアプリケーションの外部での使用を目的としたものではありません。これは、Webアプリケーションのキャッシュを提供するためにASP.NETで使用するために設計およびテストされました。コンソールアプリケーションやWindowsフォームアプリケーションなどの他の種類のアプリケーションでは、ASP.NETキャッシュが正しく機能しない場合があります。

ASP.NETキャッシュのクラスは、System.Web.dllのSystem.Web.Caching.Cacheです。ただし、キャッシュオブジェクトを単純に新規作成することはできません。System.Web.HttpRuntime.Cacheから取得する必要があります。

Cache cache = System.Web.HttpRuntime.Cache;

ASP.NETキャッシュの操作については、MSDNのここに記載されています

長所:

  1. それはだビルトイン
  2. .NET 1.0構文にもかかわらず、使用はかなり簡単です。
  3. Webコンテキストで使用すると、十分にテストされています。Googleの検索によると、.NET 2.0以降を使用している限り、Microsoftが推奨しているにもかかわらず、Webコンテキスト以外で問題が発生することは一般的には知られていません。
  4. アイテムが削除されたときにデリゲートを介して通知を受けることができます。これは、アイテムを存続させる必要があり、アイテムの優先度を事前に設定できなかった場合に必要です。
  5. 個々のアイテムには、この記事の上部にある削除方法のリストにある、(a)、(b)、または(c)の有効期限と削除の方法のいずれかの柔軟性があります。有効期限の動作を物理ファイルの存在と関連付けることもできます。

短所:

  1. 静的であるだけでなく、1つしかありません。キャッシュの独自の静的インスタンスを使用して独自のタイプを作成することはできません。アプリ全体で1つのバケットしか持てません。キーにプレフィックスを事前に挿入するなどの処理を行う独自のラッパーでバケットをラップし、キーと値のペアを引き出すときにこれらのプレフィックスを削除できます。しかし、まだバケットは1つしかありません。すべてがひとまとめにされています。これは、たとえば、3つまたは4つの異なる種類のデータを別々にキャッシュする必要があるサービスがある場合に非常に厄介になる可能性があります。これは、哀れなほど単純なプロジェクトにとっては大きな問題ではないはずです。ただし、プロジェクトの要件が原因でプロジェクトがかなり複雑な場合、通常はASP.NETキャッシュでは不十分です。
  2. アイテムは消えることがあります。多くの人がこれに気づいていません—このキャッシュの実装に関する知識を更新するまで、私は気づいていませんでした。既定では、ASP.NETキャッシュは、アイテムが「感じた」ときにアイテムを破棄するように設計されています。具体的には、この記事の冒頭にあるキャッシュテーブルの定義の(c)を参照してください。同じプロセス内の別のスレッドがまったく異なる何かに取り組んでいて、優先度の高いアイテムをキャッシュにダンプする場合、.NETがメモリを必要とすると判断するとすぐに、キャッシュ内のアイテムの破棄を開始します。それらの優先順位、低い優先順位が最初に。キャッシュアイテムを追加するためにここに記載されているすべての例では、メモリクリアの目的でキャッシュアイテムが削除されないようにするNotRemovable優先度値ではなく、デフォルトの優先度を使用していますが、有効期限ポリシーに従って削除されます。
  3. キーは文字列である必要があります。たとえば、レコードが長整数または整数でキー設定されているデータレコードをキャッシュする場合は、最初にキーを文字列に変換する必要があります。
  4. 構文が古くなっています。これは.NET1.0構文であり、ArrayListやHashtableよりも醜いです。ここにはジェネリックはなく、IDictionary <>インターフェースもありません。これには、Contains()メソッド、Keysコレクション、標準イベントはありません。Get()メソッドとGet()と同じことを行うインデクサーのみがあり、一致するものがない場合はnullを返し、さらにAdd()、Insert()(冗長?)、Remove()、およびGetEnumerator()を返します。 。
  5. デフォルトの有効期限/削除動作を設定するというDRYの原則無視するため、それらを忘れることができます。追加するアイテムを追加するたびに、どのようにアイテムを期限切れにするか、または削除するかをキャッシュに明示的に指示する必要があります。
  6. 追加されたときのタイムスタンプなど、キャッシュされたアイテムのキャッシュの詳細にアクセスする方法はありません。ここではカプセル化が少し行き過ぎており、コード内でキャッシュされたアイテムを別のキャッシュメカニズム(つまりセッションコレクション)に対して無効にする必要があるかどうかを判断しようとしているときに、キャッシュを使用するのが難しくなっています。
  7. 削除イベントイベントとして公開されないため、追加時に追跡する必要があります。
  8. そして、私がそれを十分に言っていない場合、マイクロソフトはウェブの外でそれに対して明示的に推奨します。また、.NET 1.1に呪われている場合は、Webの外部で安定性を確信して使用することは想定されていないため、気にしないでください。

.NET4.0のObjectCache / MemoryCache

Microsoftはついに、最新バージョンの.NET Frameworkに抽象ObjectCacheクラスを実装し、非Web設定でメモリ内の目的でObjectCacheを継承して実装するMemoryCache実装を実装しました。

System.Runtime.Caching.ObjectCacheは、System.Runtime.Caching.dllアセンブリにあります。これは、ASP.NETキャッシュにあるのと基本的に同じ.NET1.0スタイルのインターフェイスを宣言する抽象クラスです。System.Runtime.Caching.MemoryCacheはObjectCacheのメモリ内実装であり、ASP.NETキャッシュと非常によく似ていますが、いくつかの変更があります。

スライド式の有効期限を持つアイテムを追加するには、コードは次のようになります。

var config = new NameValueCollection();  
var cache = new MemoryCache("myMemCache", config);  
cache.Add(new CacheItem("a", "b"),  
    new CacheItemPolicy  
    {  
        Priority = CacheItemPriority.NotRemovable,  
        SlidingExpiration=TimeSpan.FromMinutes(30)  
    }); 

長所:

  1. これは組み込みであり、現在はWeb以外のMicrosoftによってサポートおよび推奨されています。
  2. ASP.NETキャッシュとは異なり、MemoryCacheオブジェクトインスタンスをインスタンス化できます。

    注:静的である必要はありませんが、静的である必要があります。これは、Microsoftの推奨事項です(黄色の注意を参照)

  3. アイテムが追加されたときに必ずしも存在しなくても削除イベントをサブスクライブする機能、冗長なInsert()が削除された、アイテムをCacheItemで追加できるなど、ASP.NETキャッシュのインターフェイスに対していくつかのわずかな改善が行われました。キャッシュ戦略を定義する初期化子を持つオブジェクト、およびContains()が追加されました。

短所:

  1. それでもDRYを完全に強化するわけではありません。私のわずかな経験から、スライド式の有効期限TimeSpanを一度設定して、それを忘れることはできません。率直に言って、上記のitem-addサンプルのポリシーは読みやすくなっていますが、恐ろしい冗長性が必要です。
  2. それはまだ一般的にキー設定されていません。キーとして文字列が必要です。したがって、データレコードをキャッシュしている場合は、文字列に変換しない限り、longまたはintを格納することはできません。

DIY:自分で作る

明示的またはスライド式の有効期限を実行するキャッシングディクショナリを作成するのは、実際には非常に簡単です。(メモリをクリアする目的でアイテムを自動削除する場合は、非常に難しくなります。)必要な作業は次のとおりです。

  1. タイプTの値、値がキャッシュに追加されたときに格納するタイプDateTimeのTimeStampプロパティ、およびタイムスタンプからどれだけ離れているかを示すTimeSpanを含むExpiringやExpirableなどの値コンテナクラスを作成します。アイテムの有効期限が切れます。明示的な有効期限については、タイムスタンプで減算された日付を指定してTimeSpanを設定するプロパティセッターを公開するだけです。
  2. IDictionaryを実装するクラスを作成します。これをExpirableItemsDictionaryと呼びましょう。私はそれをコンシューマーによって定義されたジェネリッククラスにすることを好みます。
  3. #2で作成したクラスで、Dictionary>をプロパティとして追加し、InnerDictionaryと呼びます。
  4. #2で作成されたクラスのIDictionaryが、キャッシュされたアイテムを格納するためにInnerDictionaryを使用する必要がある場合の実装。カプセル化は、上記の#1で作成されたタイプのインスタンスを介してキャッシュメソッドの詳細を非表示にします。
  5. インデクサー(this [])、ContainsKey()などが、値を返す前に、期限切れのアイテムをクリアし、期限切れのアイテムを削除するように注意してください。アイテムが削除された場合、ゲッターでnullを返します。
  6. すべてのゲッター、セッター、ContainsKey()で、特に期限切れのアイテムをクリアするときに、スレッドロックを使用します。
  7. 期限切れのためにアイテムが削除されるたびにイベントを発生させます。
  8. System.Threading.Timerインスタンスを追加し、初期化中にそれをリグして、15秒ごとに期限切れのアイテムを自動削除します。これは、ASP.NETキャッシュと同じ動作です。
  9. アイテムのコンテナー(Expiringインスタンス)のタイムスタンプが既に存在する場合はそれを置き換えることにより、スライド式の有効期限をプッシュするAddOrUpdate()ルーチンを追加することをお勧めします。

マイクロソフトは、ユーザーベースが元のデザインに依存しているため、元のデザインをサポートする必要がありますが、それはそれらが優れたデザインであることを意味するものではありません。

長所:

  1. 実装を完全に制御できます。
  2. デフォルトのキャッシュ動作を設定し、アイテムを追加するたびにキャッシュの詳細を宣言せずにキーと値のペアをドロップするだけで、DRY強化できます。
  3. 最新のインターフェース、つまりを実装できますIDictionary<K,T>。これにより、そのインターフェイスが辞書インターフェイスとしてより予測可能になるため、消費がはるかに簡単になります。さらに、IDictionary <>で機能するヘルパーや拡張メソッドにアクセスしやすくなります。
  4. キャッシュの詳細は、パブリック読み取り専用プロパティを介してInnerDictionaryを公開するなど、カプセル化を解除できます。これにより、キャッシュ戦略に対して明示的な単体テストを記述したり、それに基づいて構築された追加のキャッシュ戦略で基本的なキャッシュ実装を拡張したりできます。
  5. ASP.NETキャッシュまたはCachingApplicationBlockの.NET1.0スタイルの構文に既に慣れている人にとっては必ずしも馴染みのあるインターフェイスではありませんが、インターフェイスを好きなように定義できます
  6. キーには任意のタイプを使用できます。これが、ジェネリックが作成された理由の1つです。すべてが文字列でキー設定されるべきではありません。

短所:

  1. Microsoftによって発明されたものでも、承認されたものでもないため、同じ品質保証はありません。
  2. 上記の命令のみが実装されていると仮定すると、優先度に基づいてメモリをクリアするためのアイテムを「意地悪」にクリアしません(これはとにかくキャッシュのコーナーケースユーティリティ関数です..キャッシュを使用する場所でRAMを購入します、RAMは安いです)。

これら4つのオプションすべての中で、これが私の好みです。この基本的なキャッシュソリューションを実装しました。これまでのところ、完全に機能しているようで、既知のバグはありません(コメントがある場合は、以下のコメントまたはjon-at-jondavisまでご連絡ください!!)。必要なすべての小規模なサイドプロジェクトで使用する予定です。基本的なキャッシュ。ここにあります:

Githubリンク:https//github.com/kroimon/ExpirableItemDictionary

古いリンク:ExpirableItemDictionary.zip

言及する価値がある:AppFabric、NoSQLなど

このブログ記事のタイトルは、「ヘビーデューティーキャッシング」ではなく「シンプルキャッシング」を示していることに注意してください。ヘビーデューティーなものに取り掛かりたい場合は、専用のスケールアウトソリューションを検討する必要があります。



3

MemoryCacheとは、メモリに保存されているキャッシュのことです。

HttpRuntime.Cache(http://msdn.microsoft.com/en-us/library/system.web.httpruntime.cache(v = vs.100).aspxおよびhttp://msdn.microsoft.com/en-を参照) us / library / system.web.caching.cache.aspx)は、アプリケーションで構成したものに依存します。

たとえば、「ASP.NET 4.0:カスタム出力キャッシュプロバイダーの作成」 http://weblogs.asp.net/gunnarpeipman/archive/2009/11/19/asp-net-4-0-writing-custom-output-cacheを参照してください。 -providers.aspx


1
うーん、OutputCacheとOutputCacheProviderの実装について話しているので、2番目のリンクが誤解を招くものではないかどうかはわかりません。
giedrius 2012

うーん、別の構成を使用してSystem.Web.Caching.Cacheを永続化できると言う場所が見つかりません
Giedrius 2012

2

Coreには「System.Web.Caching」と「HttpRuntime」がないため、従来のASP.NETMVCアプリをASP.NETCoreに移行する場合、MemoryCache.Defaultは「ブリッジ」としても機能します。

また、boolアイテムを20000回保存するための小さなベンチマーク(およびそれを取得するための別のベンチマーク)を作成しました。MemoryCacheは2倍遅いようです(27ミリ秒対13ミリ秒-すべての20k回の反復の合計)が、どちらも超高速であり、おそらく無視することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.