7

インスタンス メンバーへのアクセスをロックする必要がありますか?

例:

public class HttpModule : IHttpModule
{
    //...

    Dictionary<int, int> foo;

    void UseFoo(int a, int b)
    {
        foo[a] = b;
    }
}
4

4 に答える 4

4

これまでのところ、MSDN のドキュメントからは明らかではありませんが、答えを知っていると主張する誰かからのフォーラム投稿を見つけました。実装で悪いことが起こるとは思わないように思えますが、IIS がそのプールに保持することを選択するたびに作成されるため、状態が必ずしもすべての結果で共有されるとは限らないことに注意してくださいfooHttpModuleHttpApplication

于 2010-04-11T23:24:20.187 に答える
2

IIS6で観察したように、この質問に関連する私の調査結果をここに提供したいと思います。

私はIIS6でこの問題に幅広く取り組んできましたが、log4netとリフレクションを使用して実行履歴をキャプチャする興味深い結果をいくつか見つけました。私が見つけたのは、舞台裏で行われている広範な「スレッド管理」があるということです。1:1に対応する「プライマリ」シリーズのスレッドがあるようHttpApplicationです。ただし、これらのスレッドは、要求のパイプラインを排他的に処理するわけではありません。さまざまな異なるサブスレッドこれらのインスタンスにアクセスしたときに呼び出されます。アプリケーションで使用される後続の新しいリクエストとリソースリクエストは、元のリクエストに関連する永続的な情報を共有しているように見えますが、ある種の関係を示す最初のスレッドによって完全に処理されることはありません。一見ランダムに見えるため、どの要素が他のスレッドに分割されているかについて、具体的なパターン(以前に説明したもの以外)を識別できませんでした。この証拠に対する私の結論は、階層的プーリングの概念があるということですか?参照要素の不明なサブセットが親参照を介して子スレッドに継承される場合に発生します。

答えとして、それはスレッド間で共有されてHttpModules いると言えます。インスタンス値のロックに関して、これは、値がモジュールを使用し、何らかの状態を維持する必要があるすべての要求に適用される場合に適用されます。これは、確認に費用がかかるステートフルインスタンス値を維持して、後続のリクエストで再利用できるようにする場合に役立つことがわかりました。

この問題はしばらくの間私を悩ませていました。うまくいけば、この情報が誰かを助けてくれます。

于 2012-08-09T18:41:04.967 に答える
1

Jim が投稿した記事は興味深いものですが、Jim が言うように、スレッド セーフについては何も言及していません。

静的メンバーを初期化する場合、または「一度だけ」初期化を実行する場合、つまり静的リソースを初期化する場合にのみ、ロックメカニズムが必要になると思います。

MSDN や Jim が言及した記事から、非静的クラス変数を初期化するときにロック メカニズムが必要であると結論付けることはできませんでした。

于 2011-12-13T13:58:17.180 に答える
1

私は最近、この質問に少し触れている記事を見つけました :回

スレッドについては言及されていませんが、ワーカープロセスが

必要と思われる数の HttpApplication オブジェクトをインスタンス化してから、パフォーマンス上の理由からそれらをプールし、新しいリクエストが入ってきたらインスタンスを再利用してからプールに送り返します。

リンクからのコードに従うと、init コードがスレッドセーフな方法で 1 回実行されることを確認できます。

private static bool HasAppStarted = false; 
private readonly static object _syncObject = new object(); 

public void Init(HttpApplication context) 
{ 
    if (!HasAppStarted) 
    { 
        lock (_syncObject) 
        { 
            if (!HasAppStarted) 
            { 
                // Run application StartUp code here 

                HasAppStarted = true; 
            } 
        } 
    } 
}

これを実行してテストするためのテストアプリをセットアップして、それが本当かどうかを確認するつもりでしたが、時間がありませんでした.

于 2010-04-11T23:43:16.643 に答える