0

データ アクセス レイヤー (DAL) のメモリ内キャッシュを処理するオブジェクトがあり、それをスレッド間で永続化する必要があります。私が読んだことから、好ましい方法は httpcontext.item を次のようなコードで使用することです:

   Shared Property DALList() As Dictionary(Of String, DAL)
        Get
            If Not Web.HttpContext.Current.Items.Contains("_DALList") Then
                Web.HttpContext.Current.Items.Add("_DALList", New Dictionary(Of String, DAL))
            End If
            Return Web.HttpContext.Current.Items("_DALList")
        End Get
        Set(ByVal value As Dictionary(Of String, DAL))
            If Not Web.HttpContext.Current.Items.Contains("_DALList") Then
                Web.HttpContext.Current.Items.Add("_DALList", value)
            Else
                Web.HttpContext.Current.Items("_DALList") = value
            End If
        End Set
    End Property

2 つの質問: これはオブジェクトをシリアル化しようとしていますか?もしそうなら、どうすればオブジェクトをそのままにして、シリアル化する代わりにメモリ内で参照することができますか? オブジェクトは内部で DB 接続とキャッシュを処理するため、オブジェクトをそのままにしておく必要があります。

[編集]

これを実行すると、ページがハングするエラーが発生します。イベント ログには 2 つの項目があります。

障害のあるアプリケーション w3wp.exe、バージョン 7.0.6001.18000、タイム スタンプ 0x47919ed8、障害モジュール kernel32.dll、バージョン 6.0.6001.18000、タイム スタンプ 0x4791ada5、例外コード 0xe053534f、障害オフセット 0x00000000002649d、プロセス ID 0x%9%0x10、アプリケーション開始時間.

状態サーバーは期限切れの TCP/IP 接続を閉じました。クライアントの IP アドレスは 127.0.0.1 です。期限切れの読み取り操作は、2009 年 4 月 7 日 20:44:29 に開始されました。

次に、コードを再ハッシュして、アイテムをセッション ID に対してディクショナリ オブジェクトに配置したところ、これらのエラーが発生しました。静的変数を使用すると問題なく動作しますが、ユーザーが他のユーザーのデータにアクセスするという元の問題があります (明らかにそれはオプションではありません)。

再ハッシュされたバージョンは次のとおりです: (これは最初の方法では機能しますが、この方法では機能しません)

Shared _CurrentScope As New Dictionary(Of String, DALScope)
Public Shared Property CurrentScope() As DALScope
    Get
        If Not _CurrentScope.ContainsKey(Web.HttpContext.Current.Session.SessionID & "_CurrentScope") Then
            _CurrentScope.Add(Web.HttpContext.Current.Session.SessionID & "_CurrentScope", New DALScope)
        End If
        Return _CurrentScope(Web.HttpContext.Current.Session.SessionID & "_CurrentScope")
    End Get
    Set(ByVal value As DALScope)
        If Not _CurrentScope.ContainsKey(Web.HttpContext.Current.Session.SessionID & "_Currentscope") Then
            _CurrentScope.Add(Web.HttpContext.Current.Session.SessionID & "_Currentscope", value)
        Else
            _CurrentScope(Web.HttpContext.Current.Session.SessionID & "_Currentscope") = value
        End If
    End Set
End Property

[編集]

同じセッションで複数の Web リクエストがある場合のロックの良い点。httpcontext.item アプローチを使用することになり、プロパティが byref ではなく byval であることに問題があることがわかりました。参照によってオブジェクトを処理するメソッドを含めるようにコードを変更したところ、これが機能するようになりました。

4

3 に答える 3

2

HttpContext は、単一のリクエストの有効期間内に存在します。ここのスレッドでは、複数のリクエスト間で状態を維持することについて話していると思います。もしそうなら HttpContext.Items はあなたが望むものではありません。アプリケーション キャッシュまたはその他のキャッシュ メカニズムを使用する必要があります。

補足として、項目を HttpContext.Items に入れてもシリアル化されません。キャッシュのシリアライゼーションを使用するかどうかは、キャッシュのバッキング ストアがあるかどうかによって異なりますが、これはキャッシュ固有であるため、実際には選択したキャッシュに依存します。

編集

私の理解では、システムに入れたのと同じインスタンスへの参照が返されます。私は HttpContext を使用して、非常に多くのものがある nHibernate セッションを保存します。すばらしい作品。

于 2009-04-08T00:18:17.697 に答える
0

私は間違っているかもしれませんが、ロックが実装されているとは思えません。多くのスレッドがオブジェクトを作成/使用/変更しようとすると、あらゆる種類の問題が発生することが予想されます。

于 2009-04-08T01:10:37.867 に答える
0

Josh が既に述べたように、単一のリクエスト中にキャッシュしたい場合は、httpcontext.items が最適です。これが機能しない場合は、何か間違ったことをしているに違いありません.httpcontext.itemsにデータを正確にどこに追加しますか? 私は通常、httpmodule を使用して begin_request ハンドラーにデータを追加しますが、それはすべて、何をしようとしているのかによって異なります

于 2009-04-08T00:40:11.403 に答える