dedlfix: ASP.NET Arraywerte gehen verloren.

Beitrag lesen

Hi!

Und bei diesem weiterklicken oder dem Anklicken zum Anzeigen des anderen Strings kommt es dazu, dass die Laufvariable zurücksetzt wird und auch die Inhalte des Feldes. Das passiert unterhalb einer Minute aber nie genau zum gleichen Zeitpunkt

Mit einer genauen Erklärung tue ich mich momentan etwas schwer. Aber zumindest soviel kann ich sagen: Auch ASP.NET unterliegt den Eigenheiten des Webs, die da wären, dass zwischen zwei Requests erst einmal kein Zusammenhang besteht. Wenn man Daten zwischen zwei Requests behalten will, muss man sie einerseits in Richtung Browser schicken, der sie beim nächsten Reqeuest wieder mitsendet, oder andererseits mit Sessions arbeiten. Dabei wird der Browser anhand einer Session-ID erkannt und die zugehörigen Daten dann aus dem Session-Speicher geholt. Bei PHP merkt man das Nchtbestehen von Zusammenhängen sehr deutlich, da wird jeder Request in einer jungfräulichen Umgebung abgehandelt. ASP.NET ist da anders. Da läuft eine Anwendung im IIS üblicherweise länger als ein Request. Je nachdem wo du eine Variable erstellst, lebt diese auch nach einem Request-Ende weiter. Das ist recht gut, wenn man wie in deinem Fall, die unveränderliche Daten mehrfach (über mehrere Requests und/oder Anwender) verwenden will, ohne sie jedes Mal neu abzufragen. Aber es gibt da auch Aufräummechanismen. Der Application Pool im IIS, in dem deine ASP.NET-Anwendung läuft (einigermaßen aktuellen IIS vorausgesetzt) wird regelmäßig recyclet, also beendet und startet sich neu. Das passiert aber in der Default-Einstellung erst nach 20 Minuten idlen. (Andere Kriterien gibt's da auch noch.)

Ein weiterer Fall kann auch sein, dass du mehrere Worker Processes im Application Pool konfiguriert hast. Der Normalfall wäre 1. Mehrere WPs innherhalb eines APs werden Web Garden genannt, und sie sorgen dafür, dass die Anwendung mehrfach läuft. Sie müssten sich dann auch getrennter Speicherbereiche bedienen (vermute ich). Deine Requests können dann einmal da und beim nächsten Mal in einem anderen WP behandelt werden. Auch dann sieht das dort noch nicht gefüllte Array wie geleert aus.

Wie auch immer, ich würde mich nicht auf das Vorhandensein einmal befüllter Variablen in jedem Request verlassen und stattdessen einen Lazy-Load-Mechanismus einsetzen. Hier die C#-Variante:

private string[] dasArray;
  public string[] DasArray {
    get {
      if (dasArray == null)
        initialisieren_und_befüllen();
      return dasArray;
    }
  }

Die private Variable dasArray speichert das eigentliche Array. Beim Zugriff auf die Property DasArray wird zunächst der Zustand von dasArray befragt und selbiges bei Bedarf gefüllt. Das bereits volle oder eben erst gefüllte Array wird dann zurückgegeben. Es kommt also immer ein gefülltes Array zurück, egal ob es zwischenzeitlich aufgeräumt wurde oder dein Request anderswo abgearbeitet wird.

Erkennen kann ich es daran, dass die Laufvariable wieder auf 0 springt und bein Navigieren die Textfelder leer bleiben.

Das wäre doch ein benutzerindividueller Wert. Wenn dein Server mehrere Anwender gleichzeitig behandelt - wovon man im Web ausgehen muss -, musst du Daten, die anwenderindividuell sind, im Viewstate oder im Session-Speicher ablegen.

Wenn du da genauere Untersuchungen anstellen willst, würde ich wie folgt vorgehen: Es gibt einen Tracing-Mechanismus, der schreibt ein paar Vorgänge mit, die so rund um den Application Lifecycle (AL) und Page Lifecycle (PL) passieren. Hab ich noch nicht großartig verwenden müssen, kann ich also nicht allzuviel dazu sagen. Wenn da zu wenig geloggt wird, kannst du in die diversen Events des AL und PL Debug-Ausgaben einfügen, damit du siehst, was abgearbeitet wird. Eventuell auch die Process-ID des Worker Process (wenn es eine solche gibt) dazu notieren und vielleicht den Zustand wichtiger Variablen. Welche Methoden dazu überschrieben werden müssen oder bereits in der Global.asax vorhanden sind, findest du bei Web-Recherchen zu den genannten Stichwörtern.

Lo!