新しい.NET 4 System.Runtime.Caching MemoryCacheを使用しているMVC 3アプリケーションに問題があります。一見予測不可能な時間の後、キャッシュを停止し、空のように動作します。 ASP.NET MVCのテストビューから直接取得した次のコードを検討してください。
_MemoryCache.Default.Set("myname","fred", new CacheItemPolicy() { SlidingExpiration = new TimeSpan(0,5,0) });
Response.Write(MemoryCache.Default["myname"]);
_
動作していると、予想どおり「fred」が印刷されます。ただし、Set()
にもかかわらず、問題が発生し始めると、_MemoryCache.Default["myname"]
_の値はnullになります。 Response.Write()
行にブレークポイントを設定し、イミディエイトウィンドウを使用してキャッシュから直接設定および読み取りを行うことにより、これを証明できます-設定しないだけでnullのままです!それを再び機能させる唯一の方法は、AppDomainをリサイクルすることです。
興味深いことに、Response.Write()
行を中断してMemoryCache.Default.Dispose()
を実行することで、アプリが正常に動作しているときに問題を引き起こすことができます。その後、MemoryCache.Default自体はnullではありません(これはなぜですか?)が、設定されているものは保存されません。エラーは発生しませんが、何も保存されません。
誰でもこれを確認して説明できますか?私が発見したと思うが、アプリが単独で動作を停止すると、somethingは_MemoryCache.Default
_を破棄しますが、それは私ではありません!
[〜#〜] update [〜#〜]
さて、私は今この問題にうんざりしています! CLRProfilerはMVC 3で動作しないようです。SciTechのCLRツールは良かったです。RedGateANTSも良かったです。しかし、彼らが私に言ったのは、MemoryCacheオブジェクトがsomethingによって破棄されていることだけです!また、(OutputCacheAttributeで指定された)キャッシュされるページ上のPartialViewが数分後にキャッシュされるのを停止することを(タイムスタンプ印刷を介して)証明しました-ページへの呼び出しごとに更新が開始されます。環境を明確にするために、Win 7 Ultimateを実行している開発ワークステーションのIIS 7.5サーバーで直接実行しています。上記のメモリツールは、プレイ中のオブジェクト。
必死になって、キャッシュコードを変更して、最初にアンビエントHttpContextを検索し、そのキャッシュ機能が利用可能であれば、その機能をフックして使用します。初期のテストではこれが信頼できることが示されていますが、厄介なハッキングのように感じられます。
MemoryCacheとOutputCacheがMVC 3で動作することを保証されていないという感覚を得ています...
だから、ここにいくつかのニュースがあります。これを調査しました。はい、これは.NET 4のバグです。
良いニュースは、.NET 4.5で修正されたことです。可能な場合は、インストールを.NET 4.5に更新してください。
もう1つの良いニュースは、この修正が.NET 4にバックポートされ、QFE(クイック修正...適用される1回限りの修正)#578315として利用できることです。数日前にバックポート/修正されたため、できるだけ早くリリースされるはずです。正確な日付を取得しようとしますが、間もなくです。
その他の良いニュースは、QFEの前に.NET 4でこれに対する回避策があることです。回避策は奇妙ですが、ブロックされない可能性があります。
using (ExecutionContext.SuppressFlow()) {
// Create memory cache instance under disabled execution context flow
return new YourCacheThing.GeneralMemoryCache(…);
}
お役に立てれば。
更新:修正プログラムは http://support.Microsoft.com/kb/282884 で、ここからリクエストできます: https://support.Microsoft.com/contactus/emailcontact。 aspx?scid = sw;%5BLN%5D; 1422
同じ問題があります。しばらくしてキャッシュが破棄されたことを確認します。プライベートフィールド_disposedは1になりました。コードでcache.Disposeを呼び出す必要はありません。しかし、私が見たReflectorでMemoryCacheのコードを見たとき、コンストラクターで2つのイベントをサブスクライブしました
domain.DomainUnload += eventHandler;
domain.UnhandledException += exceptionEventHandler;
private void OnAppDomainUnload(object unusedObject, EventArgs unusedEventArgs)
{
this.Dispose();
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs)
{
if (!eventArgs.IsTerminating)
return;
this.Dispose();
}
これらのイベントハンドラーは両方ともDisposeを呼び出します。 IISでのドメインリサイクルの後、ドメインのアンロードが発生しますが、キャッシュをメモリに保持します(可能な場合はシュアしません)。
私はまったく同じ症状を経験しています。最終的に、代わりにSystem.Web.Cacheクラスを使用し、HttpContext.Cacheにフックすることになりました。過去3日間完全に機能しています。
同じ問題に関連するこれらのリンクも参照してください。
統合パイプラインモードのWebAppで使用すると、PollingIntervalの後にMemoryCacheが破棄されます
MemoryCacheが魔法のように破棄状態になる
http://social.msdn.Microsoft.com/Forums/en-US/netfxbcl/thread/1233ffb3-6480-431b-94ca-1190f96cf5f6
MemoryCache
は、メモリ制限に達するとアイテムを自動的に削除します。これはあなたのケースで起こっている可能性があります、キャッシュに多くのアイテムがありますか?
configuration で制限を制御できます。デフォルトでは、利用可能なメモリに基づいて最適化されます。
確実にDispose
を呼び出すと、MemoryCache
インスタンスの動作が停止します。これは、管理されていないすべてのリソースを破棄できるようにクリーンアップするためです。 Dispose
をこれ以上使用しない場合にのみ、MemoryCache
を呼び出す必要があります。あなたがそれを呼び出すとき以外は、これがあなたの場合の問題に必要だとは思わない。