Kurze Frage
Ich habe eine Schleife, die 180.000 Mal läuft. Am Ende jeder Iteration sollen die Ergebnisse an eine TextBox angehängt werden, die in Echtzeit aktualisiert wird.
Verwenden von MyTextBox.Text += someValue
führt dazu, dass die Anwendung sehr viel Speicher verbraucht und nach einigen tausend Datensätzen nicht mehr genügend Speicher verfügbar ist.
Gibt es eine effizientere Möglichkeit, Text an TextBox.Text
180.000 Mal anzuhängen?
Bearbeiten Das Ergebnis dieses speziellen Falls ist mir wirklich egal, aber ich möchte wissen, warum dies ein Speicherfresser zu sein scheint und ob es eine effizientere Möglichkeit gibt, Text an eine TextBox anzuhängen.
Lange (Original) Frage
Ich habe eine kleine App, die eine Liste von ID-Nummern in einer CSV-Datei liest und für jede einen PDF-Bericht generiert. Nachdem jede PDF-Datei generiert wurde, ResultsTextBox.Text
wird die ID-Nummer des Berichts angehängt, der verarbeitet wurde und der erfolgreich verarbeitet wurde. Der Prozess wird in einem Hintergrundthread ausgeführt, sodass die ResultsTextBox in Echtzeit aktualisiert wird, wenn Elemente verarbeitet werden
Ich führe die App derzeit mit 180.000 ID-Nummern aus, aber der Speicher, den die Anwendung belegt, wächst im Laufe der Zeit exponentiell. Es beginnt bei ungefähr 90 KB, aber bei ungefähr 3000 Datensätzen nimmt es ungefähr 250 MB ein und bei 4000 Datensätzen nimmt die Anwendung ungefähr 500 MB Speicher ein.
Wenn ich die Aktualisierung der Ergebnistextbox auskommentiere, bleibt der Speicher mit ungefähr 90 KB relativ stationär, sodass ich davon ausgehen kann, dass geschrieben wird ResultsText.Text += someValue
dazu führt, dass der Speicher belegt wird.
Meine Frage ist, warum ist das so? Was ist eine bessere Möglichkeit, Daten an eine TextBox.Text anzuhängen, die keinen Speicher verbraucht?
Mein Code sieht folgendermaßen aus:
try
{
report.SetParameterValue("Id", id);
report.ExportToDisk(ExportFormatType.PortableDocFormat,
string.Format(@"{0}\{1}.pdf", new object[] { outputLocation, id}));
// ResultsText.Text += string.Format("Exported {0}\r\n", id);
}
catch (Exception ex)
{
ErrorsText.Text += string.Format("Failed to export {0}: {1}\r\n",
new object[] { id, ex.Message });
}
Es sollte auch erwähnenswert sein, dass die App eine einmalige Sache ist und es keine Rolle spielt, dass es einige Stunden (oder Tage :) dauern wird, bis alle Berichte erstellt sind. Mein Hauptanliegen ist, dass es nicht mehr läuft, wenn es das Systemspeicherlimit erreicht.
Ich bin in Ordnung, wenn ich die Zeile verlasse, in der die Ergebnisse aktualisiert werden, die TextBox auskommentiert hat, um dieses Ding auszuführen, aber ich würde gerne wissen, ob es eine speichereffizientere Möglichkeit gibt, Daten TextBox.Text
für zukünftige Projekte an a anzuhängen .
StringBuilder
den Text mit a anzuhängen, und dann nach Abschluss denStringBuilder
Wert dem Textfeld zuweisen .