1

妥当なパフォーマンスを達成するために、大規模なビジネス オブジェクト コレクションの永続性を必要とする一連のアプリケーション コンポーネントがあります。これは基本的に、データベースから読み取られ、後で再利用するためにオブジェクトにハイドレートされるデータです。

このオブジェクト コレクションは元々 .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

私はこれを昨日入れましたが、それ以来桃色です。

4

1 に答える 1

0

確かではありませんが、キャッシュの使用方法が MSDN の例とは少し異なります。Set の代わりに add メソッドを呼び出しています。

ここで私が見つけた例:

Private Sub btnGet_Click(ByVal sender As Object, ByVal e As EventArgs) 
    Dim cache As ObjectCache = MemoryCache.[Default] 
    Dim fileContents As String = TryCast(cache("filecontents"), String) 

    If fileContents Is Nothing Then 
        Dim policy As New CacheItemPolicy() 
        Dim filePaths As New List(Of String)() 
        filePaths.Add("c:\cache\example.txt") 

        policy.ChangeMonitors.Add(New HostFileChangeMonitor(filePaths)) 

        ' Fetch the file contents.
        fileContents = File.ReadAllText("c:\cache\example.txt") 

        cache.[Set]("filecontents", fileContents, policy) 
    End If 

    Label1.Text = fileContents
End Sub

ここにあります:MemoryCacheクラス

あなたはまた、ASP.NETアプリケーションでコンポーネントをホストするときにこの問題が発生すると言いますHttpContext.Current.Cache.ASP.NETでは、あなたが現在使用しているこのMemoryCacheがすでにこれを行っている可能性があります.以前はわかりませんが、Add を Set に変更して HttpContext のものを使用すると、どのように機能しますか? ASP.NET アプリケーションで実行されていない場合は null になるため、HpptContext.Current を確認してください。

注意すべきもう 1 つの点は、デバッガーをアタッチするときに、本当に Cache.Add/Set メソッドを実行するかということです。

于 2011-09-12T20:31:36.603 に答える