189

ASP.NET Webサイトでは、静的クラスは各Web要求に固有ですか、それとも必要に応じてインスタンス化され、GCがそれらを破棄することを決定したときにGCされますか?

私が尋ねる理由は、以前にC#でいくつかの静的クラスを作成したことがあり、動作が予想とは異なるためです。静的クラスは各リクエストに固有であると期待していましたが、そうではないようです。

それらが各リクエストに固有でない場合、それらを許可する方法はありますか?

更新:
driisが私に与えた答えは、まさに私が必要としていたものでした。私はすでにシングルトンクラスを使用していましたが、静的インスタンスを使用していたため、ユーザーが異なっていてもリクエスト間で共有されていました。この場合は悪いことでした。を使用HttpContext.Current.Itemsすると、私の問題は完全に解決します。将来この質問に出くわした人のために、パターンを理解しやすいように簡略化および短縮した私の実装を以下に示します。

using System.Collections;
using System.Web;

public class GloballyAccessibleClass
{
    private GloballyAccessibleClass() { }

    public static GloballyAccessibleClass Instance
    {
        get
        {
            IDictionary items = HttpContext.Current.Items;
            if(!items.Contains("TheInstance"))
            {
                items["TheInstance"] = new GloballyAccessibleClass();
            }
            return items["TheInstance"] as GloballyAccessibleClass;
        }
    }
}
4

5 に答える 5

151

静的クラスと静的インスタンスフィールドは、アプリケーションへのすべてのリクエスト間で共有され、アプリケーションドメインと同じ有効期間があります。したがって、静的インスタンスを使用する場合は、同期の問題などが発生する可能性があるため、注意が必要です。また、アプリケーションプールがリサイクルされる前に静的インスタンスがGCされることはないため、静的インスタンスによって参照されるすべてのものがGCされることはないことにも注意してください。これにより、メモリ使用量の問題が発生する可能性があります。

リクエストと同じ有効期間のインスタンスが必要な場合は、HttpContext.Current.Itemsコレクションを使用することをお勧めします。これは、リクエストを通じて必要なものを保存するための設計によるものです。デザインと読みやすさを向上させるために、シングルトンパターンを使用してこれらのアイテムを管理できます。インスタンスをに格納するシングルトンクラスを作成するだけHttpContext.Current.Itemsです。(ASP.NETの共通ライブラリには、この目的のための汎用SingletonRequestクラスがあります)。

于 2008-10-12T09:51:34.513 に答える
13

タイプはアプリドメインに含まれているため、アプリドメインがリサイクルされない限り、またはリクエストが別のアプリドメインによって処理される場合は、静的クラスが存在することを期待します。

特定のリクエストに固有のオブジェクトを作成する方法はいくつか考えられます。たとえば、Application.BeginRequestでオブジェクトをインスタンス化し、HttpRequestオブジェクトに保存して、のすべてのオブジェクトからアクセスできるようにすることができます。リクエスト処理パイプライン。

于 2008-10-12T02:30:05.887 に答える
4

それらが各リクエストに固有でない場合、それらを許可する方法はありますか?

いいえ。静的メンバーは ASP.NET プロセスによって所有され、Web アプリのすべてのユーザーによって共有されます。セッション変数など、他のセッション管理手法に目を向ける必要があります。

于 2008-10-12T02:57:37.173 に答える
2

通常、静的メソッド、プロパティ、およびクラスは、Applicationレベルで一般的です。アプリケーションが存続する限り、それらは共有されます。

ThreadStatic属性を使用して、別の動作を指定できます。その場合、それらは現在のスレッドに固有であり、これは各リクエストに固有であると私は思います。
複雑すぎるようですが、これはお勧めしません。

を使用HttpContext.Current.Itemsして、1つのリクエストに対応するようにHttpContext.Current.Session設定したり、1人のユーザーに対応するように設定したりできます(リクエスト間で)。

ただし、一般的には、のようなものを使用する必要がない限りServer.Transfer、基本的に一度作成してから、メソッド呼び出しを介して明示的に渡すのが最善の方法です。

于 2008-10-12T10:02:21.370 に答える