Das Application- und Session-Objekt in ASP stellen praktische Container zum Zwischenspeichern von Daten im Arbeitsspeicher bereit. Sie können Daten sowohl dem Application- als auch dem Session-Objekt zuweisen. Diese Daten verbleiben zwischen HTTP-Aufrufen im Arbeitsspeicher. Sitzungsdaten werden auf Benutzerbasis gespeichert, während die Anwendungsdaten für alle Benutzer freigegeben werden.
Wann werden die Daten in die Anwendung oder Sitzung geladen? Die Daten werden häufig beim Starten einer Anwendung oder Sitzung geladen. Um Daten beim Anwendungs- oder Sitzungsstart zu laden, fügen Sie Application_OnStart() oder Session_OnStart(), den jeweils geeigneten Code hinzu. Diese Funktionen müssen sich in der Datei Global.asa befinden. Ist dies nicht der Fall, können Sie sie hinzufügen. Sie können die Daten auch erst laden, wenn sie zum ersten Mal benötigt werden. Fügen Sie Ihrer ASP-Seite zu diesem Zweck Code hinzu, der prüft, ob die Daten vorhanden sind, und sie lädt, wenn dies nicht der Fall ist (oder schreiben Sie eine entsprechende wiederverwendbare Skriptfunktion). Dies ist ein Beispiel der klassischen Leistungsmethode, die als verzögerte Auswertung bezeichnet wird. Bei dieser wird eine Berechnung erst bei Bedarf durchgeführt. Dazu ein Beispiel:
<%
Function GetEmploymentStatusList
Dim d
d = Application(„EmploymentStatusList“)
If d = „„ Then
‚ FetchEmploymentStatusList function (not shown)
‚ fetches data from DB, returns an Array
d = FetchEmploymentStatusList()
Application(„EmploymentStatusList“) = d
End If
GetEmploymentStatusList = d
End Function
%>
Sie können ähnliche Funktionen für jeden benötigten Datenblock schreiben.
In welcher Form sollten die Daten gespeichert werden? Sie können alle Variantentypen speichern, da es sich bei allen Skriptvariablen um Varianten handelt. Sie können z. B. Zeichenfolgen, Ganzzahlen oder Arrays speichern. Sie werden häufig den Inhalt eines ADO-Recordsets in einem dieser Variablentypen speichern. Um Daten aus einem ADO-Recordset zu entnehmen, müssen Sie die Daten manuell Feld für Feld in VBScript-Variablen kopieren. Dies ist mithilfe einer der Beständigkeitsfunktionen für ADO-Recordsets, GetRows(), GetString() oder Save() (ADO 2.5), schneller und einfacher. Ausführliche Einzelheiten hierzu gehen über den Zweck dieses Artikels hinaus, aber im Folgenden sehen Sie eine Funktion, die die Verwendung von GetRows() zum Zurückgeben eines Arrays von Recordsetdaten demonstriert.
‚ Get Recordset, return as an Array
Function FetchEmploymentStatusList
Dim rs
Set rs = CreateObject(“ADODB.Recordset”)
rs.Open “select StatusName, StatusID from EmployeeStatus”, _
“dsn=employees;uid=sa;pwd=;”
FetchEmploymentStatusList = rs.GetRows() ‚ Return data as an Array
rs.Close
Set rs = Nothing
End Function
Die oben dargestellte Funktion könnte durch Zwischenspeichern des HTML-Inhalts dieser Liste statt des Arrays weiter angepasst werden. Dazu ein einfaches Beispiel:
‚ Get Recordset, return as HTML Option list
Function FetchEmploymentStatusList
Dim rs, fldName, s
Set rs = CreateObject(“ADODB.Recordset”)
rs.Open “select StatusName, StatusID from EmployeeStatus”, _
“dsn=employees;uid=sa;pwd=;”
s = “<select name=””EmploymentStatus””>” & vbCrLf
Set fldName = rs.Fields(“StatusName“) ‚ ADO Field Binding
Do Until rs.EOF
‚ Next line violates Don’t Do String Concats,
‚ but it’s OK because we are building a cache
s = s & „ <option>„ & fldName & „</option>„ & vbCrLf
rs.MoveNext
Loop
s = s & „</select>„ & vbCrLf
rs.Close
Set rs = Nothing ‚ See Release Early
FetchEmploymentStatusList = s ‚ Return data as a String
End Function
Unter den richtigen Umständen können Sie ADO-Recordsets selbst im Gültigkeitsbereich des Application- oder Session-Objekts zwischenspeichern. Dabei sind aber zwei Dinge zu beachten:
- ADO muss als Freethread-Komponente markiert sein.
- Sie müssen einen abgetrennten Recordset verwenden.
Wenn es keine Garantie dafür gibt, dass diese beiden Anforderungen erfüllt sind, sollten Sie ADO-Recordsets nicht zwischenspeichern. Im Tipp zu nicht beweglichen Komponenten und im Tipp weiter unten, in dem vom Zwischenspeichern von Datenbankverbindungen abgeraten wird, werden die Risiken beim Speichern von COM-Objekten im Gültigkeitsbereich eines Application- oder Session-Objekts behandelt.
Beim Speichern von Daten im Gültigkeitsbereich eines Application- oder Session-Objekts verbleiben die Daten in diesem, bis Sie sie durch Programmieren ändern, die Sitzung abläuft oder die Webanwendung neu gestartet wird. Was geschieht, wenn die Daten aktualisiert werden müssen? Um eine Aktualisierung von Anwendungsdaten manuell zu erzwingen, rufen Sie eine ASP-Seite auf, auf die nur der Administrator Zugriff hat, und die die Daten aktualisiert. Sie können Ihre Daten stattdessen auch in regelmäßigen Abständen mithilfe einer Funktion aktualisieren. Das folgende Beispiel speichert einen Zeitstempel mit den zwischengespeicherten Daten und aktualisiert die Daten nach einem bestimmten Zeitraum.
<%
‚ error handing not shown…
Const UPDATE_INTERVAL = 300 ‚ Refresh interval, in seconds
‚ Function to return the employment status list
Function GetEmploymentStatusList
UpdateEmploymentStatus
GetEmploymentStatusList = Application(„EmploymentStatusList“)
End Function
‚ Periodically update the cached data
Sub UpdateEmploymentStatusList
Dim d, strLastUpdate
strLastUpdate = Application(„LastUpdate“)
If (strLastUpdate = „„) Or _
(UPDATE_INTERVAL < DateDiff(„s“, strLastUpdate, Now)) Then
‚ Anmerkung: Hier können zwei oder mehr Aufrufe eingehen. Das ist in Ordnung und führt
‚ lediglich zu einigen unnötigen Abrufen (dies kann umgangen werden)
‚ FetchEmploymentStatusList function (not shown)
‚ fetches data from DB, returns an Array
d = FetchEmploymentStatusList()
‚ Update the Application object. Use Application.Lock()
‚ to ensure consistent data
Application.Lock
Application(„EmploymentStatusList“) = Events
Application(„LastUpdate“) = CStr(Now)
Application.Unlock
End If
End Sub
Ein weiteres Beispiel finden Sie im Artikel „World’s Fastest ListBox with Application Data“.
Beachten Sie, dass vom Zwischenspeichern von großen Arrays in Session- oder Application-Objekten abgeraten wird. Bevor Sie auf ein Element des Arrays zugreifen können, setzt die Semantik der Skripterstellungssprachen voraus, dass das gesamte Array kopiert wird. Wenn Sie z. B. ein aus 100.000 Elementen bestehendes Zeichenfolgenarray, das US-amerikanische Postleitzahlen lokalen Wetterstationen zuordnet, in einem Application-Objekt zwischenspeichern, muss ASP zuerst alle 100.000 Wetterstationen in ein temporäres Array kopieren, bevor Sie auch nur eine Zeichenfolge extrahieren können. In diesem Fall empfiehlt es sich, zum Speichern der Wetterstationen eine benutzerdefinierte Komponente mit einer benutzerdefinierten Methode zu erstellen oder eine der Wörterbuchkomponenten zu verwenden.
Zum Schluss noch ein weiterer Kommentar nach dem Motto „das Kind mit dem Badewasser ausschütten“. Arrays stellen schnelle Suche und Speicherung von zentralen Datenpaaren bereit, die im Arbeitsspeicher zusammenhängen. Das Indizieren eines Wörterbuches ist langsamer als das Indizieren eines Arrays. Sie sollten sich für die Datenstruktur entscheiden, die unter den gegebenen Umständen die beste Leistung bietet.