妥当なパフォーマンスを達成するために、大規模なビジネス オブジェクト コレクションの永続性を必要とする一連のアプリケーション コンポーネントがあります。これは基本的に、データベースから読み取られ、後で再利用するためにオブジェクトにハイドレートされるデータです。
このオブジェクト コレクションは元々 .net 3.5 で実装されていたので、ASP.Net ランタイムによってロードされたときにこの永続性を実現するために HttpRuntime.Cache が使用され、win フォーム クライアントによってロードされた場合はエンタープライズ ライブラリ キャッシュ ブロックが使用されました。 .
現在、.net 4.0 では、これらの要求に System.Runtime.Caching を使用できます。キャッシュされたアイテムの取得のために、次のパターンが実装されました。
Public Function GetCachedObject(cacheKey as String) as Object
Dim _returnValue as Object
SyncLock m_lockObject //some private lock object
Dim _cache as ObjectCache = MemoryCache.Default
//This is never found when debugging
If _cache.Item(cacheKey) IsNot Nothing Then
_returnValue = _cache.Item
Else
Dim _policy As New System.Runtime.Caching.CacheItemPolicy()
_policy.AbsoluteExpiration = DateTime.Now.AddHours(12)
Dim _obj as Object = MethodToGetAndHydrateObject()
_cache.Add(New CacheItem(cacheKey, _obj), _policy)
_returnValue = _obj
End If
End SyncLock
Return _returnValue
End Function
これは機能しているように見えますが、デバッガー (vs2010) が接続されていない場合に限ります。
デバッガーをアタッチすると、上記のキャッシュ存在チェックは常に何も返しません。
これらは、MSDN のキャッシュを使用する方法のかなりわかりやすい例です。私が見逃しているものはありますか、それともこれは本当に予期しない動作ですか?
更新: コンポーネントが ASP.net でホストされている場合に、これが発生していることがわかります。DLL をビルドし、それらをサイトにコピーし、いくつかのステップを実行して問題ありません。デバッガーをアタッチしてステップを再度実行するとすぐに、この動作が表示されます。
更新 2 : ここでよくあることですが、質問を投稿してからしばらくすると、デバッガーの出力ウィンドウからもう少し詳細なエラーが表示されました。このエラーの詳細から、このMS Connect の記事にたどり着きました。リモーティング (私) を使用して ASP.NET でホストされているアプリを呼び出すと、MemoryCache.Default は管理タイマー (キャッシュのクリーンアップなど) をスレッド コンテキストに結び付けているようです。スレッド コンテキストが使用できなくなると、コールバックは失敗し、MemoryCache.Default は他のすべての試行で動作を停止したように見えます。
ExecutionContext.SuppressFlow() を追加すると (以下の作り直された例に見られるように)、このアタッチメントが停止するようです。
Using ExecutionContext.SuppressFlow()
_cache = MemoryCache.Default
End Using
私はこれを昨日入れましたが、それ以来桃色です。