4

多くの非 UI コードに別のクラス ライブラリを使用する .NET Web アプリケーションがあります。このライブラリには、サイト全体の構成情報に使用される静的クラスがあります。Application_Startイベント中に初期化されます。

この重要な静的オブジェクトが断続的に状態を失っているように見えるという問題があります.DLLが何らかの理由でアンロードされているためだと思います. 何日も起こらないかもしれませんし、1日に数回起こるかもしれません。ただし、これはアプリケーションを再起動せずに発生するため、その結果、初期化中に初期化されたすべてのデータApplication_Startが失われ、あらゆる種類の問題が発生します。アプリ プールをリサイクルするか、アプリケーションを再起動すると、問題が解決します。

何が起こっているのかを把握した後、アプリケーションの開始段階ではなく、クラス ライブラリの構成オブジェクトが静的コンストラクターで初期化されるようにコードを変更しました。これは、入る価値のない他の複雑さをもたらしますが、私はそれを機能させることができます-私はそれが悪いアーキテクチャであり、必要ではないと思います.

Application_Startアプリケーションの存続期間中、その状態を維持している間にロードされた外部 DLL 内の静的オブジェクトに依存できるようにする必要がありますか? 明らかにできません - 理由はよくわかりませんが、DLL がアンロードされている理由を探す必要があるのか​​ 、それとも単純にアンロードできることを受け入れて、外部の静的オブジェクトに依存するコードを決して書かないのか疑問に思っていますメイン アプリケーション DLL が値を保持します。

Application_Start は次のようになります。

Application_Start() {

    // asp.net routing
    ConfigureRoutes();

    // LF is the static config object in an outside dll
    // the LFFactory object implements session & database stuff that's context-specific
    // (e.g. this is initialized with a different implementation when testing).

    LF.Initialize(new SiteEnvironment.Web.LFFactory());

    // add custom view engine...
    ViewEngines.Engines.Clear();
    ... blah blah 

}
4

4 に答える 4

1

問題に対処できるかどうかはわかりませんが、Web アプリケーション内で静的クラスを使用することは特に困難です。静的メソッドを持つクラス (静的またはインスタンス ベース) は問題ありませんが、静的プロパティとフィールドは混乱を引き起こします。データは IIS 内のスレッド間で共有され、一見ランダムな順序でデータが上書きされます。

静的データを共有しようとしている場合は、そのデータを web.config に入れるか、サーバーにキャッシュします。データが読み取り/書き込みの場合は、それをインスタンス ベースのオブジェクトに入れます。

于 2012-12-03T17:46:03.250 に答える
0

上記の私の質問に答える前に、または静的メンバーがどのように見えるかを知る前に、暗闇の中でショットを撮り、静的オブジェクトは、参照カウントが 0 に達すると、他のオブジェクトと同様に消失する可能性があると言います。

潜在的な解決策は、その参照を介してオブジェクトにアクセスしない場合でも、オブジェクトへの「保証された」アプリケーション永続参照を維持することです。

// for each static property we need to keep in memory
Application.Add("MyClass.property", MyClass.property);

次の 2 つの方法のいずれかでオブジェクトを取得します。

// our object should always be accessible like this
Object a = Application["MyClass.property"];

// and because we've created an application-persistent reference to the property,
// it should also be accessible like this
Object b = MyClass.property;

ただし、仮説に基づく、暗闇でのショットの提案にすぎません。

補遺: Application_Start が追跡する必要がある各静的オブジェクトを認識できると期待できない場合は、リフレクションを使用してクラスの属性を繰り返し処理し、各静的プロパティを追加することをお勧めします。

于 2012-12-03T17:45:17.147 に答える
0

主に構成データに使用している場合は、その構成データをサイトの Web.config ファイルに入れることをお勧めします。これを、現在持っているものと同様のクラスにラップすることができます(すべきですか?)。そのクラスは、構成ファイルを読み取り、結果を静的メモリに格納するいくつかのアクセサーで構成できます。何らかの理由でデータが失われた場合、アクセサーは構成ファイルからその場で再ロードするだけで何の問題もありません。

これがあなたが探しているものであることを願っています。ロードしている構成データのタイプと、XML 構成ファイルで表現/保存できるかどうかについては、完全にはわかりません。

クラスは次のようになると思います。

public static class MyConfig
{
  static MyConfig() { LoadConfigData(); }

  public static string ConnectionString
  {
    get
    {
      if (_connectionString == null) { LoadConfigData(); } //assignment of static data done here
        return _connectionString;
    }
  }
  private static string _connectionString = null;

  // repeat for other config-settings...
}
于 2012-12-03T17:14:30.813 に答える
0

あなたのアプローチは正しいです。問題は、アプリケーション プールがリサイクルされている可能性があります。これにより、共有メモリが失われます。アプリケーション プールのリサイクルのタイミングとタイミングを調整できます。

于 2013-04-26T19:11:42.443 に答える