簡體   English   中英

在單獨的DLL中具有邏輯的.NET Web項目正在卸載

[英].NET web project with logic in a separate DLL is unloading

我有一個.NET Web應用程序,它為許多非UI代碼使用單獨的類庫。 在此庫中是一個靜態類,用於站點范圍的配置信息。 它在Application_Start事件期間初始化。

我有一個問題,這個關鍵的靜態對象似乎間歇性地失去了它的狀態 - 我假設因為某些原因導致DLL被卸載。 它可能不會發生幾天,或者可能每天發生幾次。 但是, 如果沒有重新啟動應用程序,則會發生這種情況,因此結果是在Application_Start期間初始化的所有數據都將丟失,從而導致各種問題。 回收應用程序池或以其他方式重新啟動應用程序會修復它。

在我弄清楚發生了什么后,我更改了代碼,以便類庫中的配置對象使用靜態構造函數初始化自身,而不是在應用程序啟動階段。 這引入了一些其他不值得進入的復雜性,但我可以使它工作 - 我只是認為它是一個糟糕的架構,不應該是必要的。

我是否能夠依賴於在Application_Start期間加載的外部DLL中的靜態對象,以便在Application_Start的生命周期內保持其狀態? 顯然我不能 - 我不知道為什么 - 但我想知道我是否應該尋找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 

}

不確定它是否解決了您的問題,但在Web應用程序中使用靜態類特別困難。 使用靜態方法的類(基於靜態或基於實例)很好,但靜態屬性和字段將導致破壞。 您的數據將在IIS中的線程之間共享,數據將以看似隨機的順序被覆蓋。

如果您嘗試共享靜態數據,請將該數據放在web.config中或將其緩存在服務器上。 如果數據是讀/寫,則將其放在基於實例的對象中。

如果您主要用於配置數據,我建議您將該配置數據放入站點的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...
}

在回答上面的問題之前,或者知道靜態成員的樣子之前,我會在黑暗中拍攝並說當參考計數達到0時,靜態物體同樣可以消失,就像任何其他物體一樣。

一個潛在的解決方案是維護對象的“保證”應用程序持久性引用,即使您沒有通過該引用訪問該對象:

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

以下兩種方式之一檢索對象:

// 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;

只是一個假設的,暗中暗示的建議!

ADDENDUM:如果不能預期Application_Start知道它需要跟蹤的每個靜態對象,我建議使用反射迭代你的類的屬性,隨時添加每個靜態屬性。

你的方法是正確的。 問題可能是應用程序池正在回收。 這將松開共享內存。 您可以調整應用程序池何時以及是否回收。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM