DF19D316838443B787A6360721E6DBC4
  • Thomas Pollinger
  • 03.06.2019
  • DE

PreExecute: Temporary .NET Cache Files

Wenn man nun die Dinge aus den beiden ersten Artikeln beherzigt hat, dann kommt man schnell in den Bereich Optimierung. Als erstes, wenn man C# (.aspx) statt VBScript (.asp) anwendet, bekommt man es ganz schnell mit den s.g. Temporary .NET Cache Files zu tun. Denn dort legt ASP.NET bei jedem PreExecute bzw. RDExecute, bedingt durch das ASP.NET Dynamic Compilation, eine Cache-Datei an. 

Man könnte nun meinen, dass je Seite im Management Server nur eine Cache-Datei im o.g. Cache-Ordner angelegt wird. Dem ist aber nicht so, denn für ASP.NET ist jede Seitenvorschau mit PreExecute in C# eine neue Version und wird entsprechend abgelegt. 

Damit kann man sich nun schon fast denken, auf was ich nun hinaus möchte. Der Cache-Ordner wächst und wächst und wächst an ;)
 

Betroffende ASP.NET Cache-Ordner

Es handelt sich dabei um die folgenden Ordner, je nach eingesetzter ASP.NET Version:

  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\preexecute\fa260d73\ea2a5a2b
  • C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\preexecute\..

und es ist keine Besonderheit des Management Servers, sondern zu diesem Thema gibt es viele Artikel im Netz.


Hinweis: Aktuell bin ich mir nicht sicher, ob die beiden letzten zwei Segemente der das o.g. Pfades bei jeder Installation identisch sind. Jedoch ist wichtig, dass man den korrekten preexecute-Ordner ermittelt und dann darin die Unterverzeichnisse bis zu den *.compiled und *.dll usw. Dateien.


Hier mal ein Auszug aus einem Artikel dazu:

Dieser Beitrag erklärt mehr über ASP.NET Dynamic Compilation und Code hinter den Seiten in weiteren Details. Wenn Sie eine ASP.NET-Seite in einer Website erstellen, wird tatsächlich ein.NET-Code hinter der Klasse erstellt. Der gesamte Inhalt der Seite wird in eine .NET-Klasse kompiliert.

Wenn Sie eine Anfrage für eine ASP.NET-Seite gesendet haben, überprüft das Framework die entsprechende Klasse auf die Seite und wenn die Klasse nicht existiert, kompiliert das Framework die Seite in eine neue.NET-Klasse und speichert die kompilierte Klasse im temporären ASP.NET-Ordner unter der Adresse

\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

Kommt die Anfrage in Zukunft auf die gleiche Seite, wird die Seite nicht mehr kompiliert, sondern die zuvor kompilierte Klasse wird ausgeführt und kehrt zum Browser zurück. Dieser Prozess wird als ASP.NET Dynamic Compilation bezeichnet.

Wenn die ASP.NET-Seite geändert wird, wird die entsprechende.NET-Klasse automatisch gelöscht und wenn eine neue Anfrage für diese Seite kommt, wird die geänderte Seite in eine neue.NET-Klasse kompiliert.

Sie können Ihre ASP.NET-Anwendung sogar mit dem Befehlszeilentool aspnet_compiler.exe vorkompilieren. Wenn Sie die Vorkompilierung durchführen, erleben die Benutzer Ihrer Anwendung keine Verzögerung bei der Kompilierung der ersten Anforderung.

Quelle: http://www.techbubbles.com/aspnet/aspnet-dynamic-compilation/ oder https://forums.asp.net/t/1985667.aspx?ASP+NET+Dynamic+Compilation
 

Lösung für eine automatische Bereinigung

Damit dieser Ordner nicht vollläuft, muss man sich nun selbst darum kümmern, dass dieser regelmäßig bereinigt wird. Denn sonst macht sich das im Management Server mit Performance-Problemen bemerkbar.

Dazu setzen wir bei uns ein kleines PowerShell-Skript ;) ein:

$Now = Get-Date;
$Days = ("-1");
$TargetFolder = ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\preexecute\fa260d73\ea2a5a2b");
$Extension = "*.*";
$LastWrite = $Now.AddDays($Days);
If (Test-Path -Path ($TargetFolder)) {
    $Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where {$_.LastWriteTime -le "$LastWrite"};
    $Files.Count;
    ForEach ($File in $Files) {
        If ($File -ne $NULL) {
            Write-Host ("Deleting File {0} | {1}" -f $File.LastWriteTime,$File) -ForegroundColor "Red";
            Remove-Item $File.FullName | Out-Null;
        } Else {
            Write-Host "No more files to delete!" -ForegroundColor "Green";
        }
    }
}

Dieses kleine Skript löscht immer alle Dateien, welche älter als 24h zum Ausführungszeitpunkt sind. Damit wird sichergestellt, dass nicht während einer Publizierung versehendlich benötigte Dateien gelöscht werden. Jedoch ist das Skript so leistungsstark, dass man sich sicher sein kann, dass der o.g. Ordner nicht aus allen Nähten platzt ;)

Dieses PowerShell-Skript kann man entweder als Benutzerdefinierten Auftrag direkt im Management Server, für jeden Knoten im Cluster, zyklisch ausführen lassen. Oder alternativ kann man auch einen Task Scheduler Job direkt auf dem Server einrichten und diesen dann zyklisch ausführen. Beide Varianten sind valide und führen dazu, dass der Ordner bereinigt wird.


Zusammenfassung

PreExecute und RDExecute im Zusammenspiel mit ASP.NET (C#) können in allen Varianten ein hilfreiches und ergänzendes Arbeitsmittel sein. Egal ob man es für komplette ASP.NET Applikationen aus dem Management Server oder nur für eine ergänzende Funktionalität für die Publizierung nutzt. Jedoch sollte man immer auch die Systemwartung im Auge behalten. Ebenso auch die Systemleistung oder ein anderes seltsames Verhalten müssen nicht immer die Ursache im Management Server haben. ;)

Im nächsten Artikel PreExecute: Tuning, Tipps und Tricks werde ich aber auch die Optimierungs-Möglichkeiten aufzeigen. ;) 


Über den Autor:
Thomas Pollinger

... ist Senior Site Reliability Engineer bei der Vodafone GmbH in Düsseldorf. Seit dem Jahr 2007 betreut er zusammen mit seinen Kollegen die OpenText- (vormals RedDot-) Plattform Web Site Management für die deutsche Konzernzentrale.

Er entwickelt Erweiterungen in Form von Plug-Ins und PowerShell Skripten. Seit den Anfängen in 2001 (RedDot CMS 4.0) kennt er sich speziell mit der Arbeitweise und den Funktionen des Management Server aus.