2 Stimmen

XslCompiledTransform vs. XslTransform und wie wäre es mit einem OOM für gute Maßnahme?

Also für eine Weile habe ich XslCompiledTransform verwendet, weil das ist, was Microsoft sagt mir, ich muss verwenden, wie XslTransform veraltet ist. Kürzlich musste ich es mit einer Transformation verwenden, die fast 100.000 Zeilen hat (generiertes xsl - natürlich). Als ich meine Anwendung verwendete, war ich schockiert, dass ein OOM auftauchte. Egal, was ich tat - OOM ist alles, was ich bekomme... Zum Spaß ging ich zurück zu XslTransform... Genau den gleichen Code ändern XslCompiledTransform zu XslTransform und es funktioniert gut...

Kann mir jemand sagen, wie man um die OOM arbeiten - gibt es einige "swtich" auf XslCompiledTransform? Ich weiß nicht, wie Sie in der Lage sein, das genaue Problem zu replizieren, aber wenn jemand Antworten hat, sind sie sehr zu schätzen.

Danke - Code unten:

Werke:

XslTransform myXslTransform = new XslTransform();
myXslTransform.Load(xslWith100ThousandLines);
MemoryStream m = new MemoryStream();
myXslTransform.Transform(myXPathDocument, null, m);
m.Flush();
m.Close();

Scheitert mit OOM

XslCompiledTransform cxslt = new XslCompiledTransform();
cxslt.Load(xslWith100ThousandLines);
MemoryStream m = new MemoryStream();
cxslt.Transform(myXPathDocument, null, m);
m.Flush();
m.Close();

2voto

dovholuk Punkte 929

Ok, so jetzt ich denke, vielleicht ist dies mehr 'Microsoft, die Microsoft'... auf eine Vermutung änderte ich die Zielplattform zurück zu "Any CPU", schloss ALLE meine Visual Studio Instanzen öffnen und öffnete mein Projekt... ich dann bereinigt, neu kompiliert und Reran und ich bin wieder immer die OOM...

Ich habe dann die Zielplattform wieder auf x86 gesetzt und siehe da, kein OOM mehr! Ich hatte eine Menge x64-bezogener Probleme wie dieses und in Zukunft werde ich sicher sein, sie in jedem Posting zu erwähnen... meistens liegt es an x64...

merkwürdig... aber Problem 'gelöst'... :S

0voto

casperOne Punkte 72238

Zuerst dachte ich, dass Sie dies bei Microsoft Connect als Fehler melden sollten, aber wenn ich jetzt darüber nachdenke, ist es nicht wirklich ein Fehler. Bei einem so großen XSL-Dokument sind Sie höchstwahrscheinlich auf eine OOM-Ausnahme gestoßen.

Ich würde es trotzdem dort posten, nur weil ich nicht erwarten würde, dass die neue XslCompiledTransform fehlschlägt, wenn die XslTransform es nicht tut.

Wenn das Ergebnisdokument sehr umfangreich ist, sollten Sie das Dokument vielleicht in einem temporären FileStream auf der Festplatte speichern und dann mit diesem arbeiten, während Sie das Dokument verarbeiten.

0voto

Suprising, ich war unter dem Eindruck, dass die alte XslTransform nur an die neue XslCompiledTransoform verkettet.

Haben Sie den OOM bei der ersten Verwendung erhalten? Denken Sie daran, dass alles, was kompiliert wird (XslCompiledTransoform, XmlSerializer, Regex mit RegexOptions.Compiled), Assemblies in Ihre AppDomain lädt. Assemblies können nicht entfernt werden, sobald sie einer AppDomain hinzugefügt wurden. Sie haben hier einige Optionen:

  1. Laden Sie die Baugruppen in eine andere AppDomain und entfernen Sie diese AppDomain, sobald Sie mit ihr fertig sind. Dies ist ziemlich kompliziert und schwierig. Auf diese Weise kann Ihre Anwendung verwendeten Speicher freigeben.
  2. Erstellen Sie einen Cache für XslCompiledTransforms. Erstellen Sie die Transformation NIE wieder. Auf diese Weise kann Ihre Anwendung das Wachstum der Speichernutzung eindämmen. Sie können die XSL vorher mit einem Hash+Base64-Prüfsummenverfahren versehen und diese Zeichenfolge als Schlüssel im Wörterbuch verwenden.

Wenn Sie die XSLT-Datei zur Entwurfszeit generieren, kann es sich lohnen, die von ihr erstellte Assembly abzurufen und sie anstelle der XSLT mit Ihrer Anwendung zu verpacken. Wenn dies zur Laufzeit geschieht, müssen Sie die obige Option (1) wählen.

0voto

dovholuk Punkte 929

Nun ja... die Programmierung in der Windows-Welt ist immer ein Rätsel...

ich danke Ihnen beiden für Ihre Antworten, aber heute - beim Versuch, das Problem zu reproduzieren (nachdem ich etwa 14 Stunden weg war), ist das Problem völlig verschwunden...

das einzige, was ich anders gemacht habe, war, den Compiler auf x86 statt x64 einzustellen, und jetzt funktioniert der Code genau so, wie ich es am Anfang erwartet hätte, und ich bin verwirrter denn je...

Nur damit jeder weiß, dass ich nicht verrückt bin, hier ist der Task-Manager-Schnappschuss von zwei aufeinanderfolgenden Durchläufen: alt text

Ich bin mir nicht sicher, wie oder warum... aber da ist das...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X