Wie kann ich die Leistung von FlowDocumentScrollViewer erhöhen?

9

In einer früheren Frage habe ich gefragt, wie man Echtzeit-Logging-Ausgaben in einem WPF-Textfeld-ähnlichen Element erhält ( WPF hängt Textblöcke stark an Benutzeroberflächen-Threads an, aber WinForms nicht? ). Die Antwort dort führte mich dazu, eine FlowDocumentScrollViewer zu verwenden, die tatsächlich viel schneller war als RichTextBox . Ich habe jedoch festgestellt, dass das Ausführen von Befehlen mit einer großen Menge an Textausgaben (wie 'svn co') zu einer merklichen Verlangsamung in meiner WPF-Anwendung führt. Das Wechseln der Tabs nach dem Auschecken von 3 oder 4 sehr großen SVN-Zweigen dauert 3-4 Sekunden, und ich bin mir sicher, dass die Zeit mit der Anzahl der Checkouts steigen würde, die ich mache. Scrollen hat auch merkliche Verzögerung.

Wie in der oben verlinkten Frage angegeben, habe ich kürzlich meine Anwendung von Windows Forms auf WPF umgestellt. Ich mag WPF sehr - es gibt viele Vorteile, die ich in Forms nicht hatte. Allerdings scheint die Performance in WPF ein Problem zu sein, zumindest für mich. In der Forms-Version meiner Anwendung konnte ich große Mengen an Text an die RichTextBox -Kontrolle drucken und hatte keinerlei Einschränkungen in meiner App. Das Wechseln der Tabs erfolgte sofort und das Scrollen war nahtlos. Dies ist die Erfahrung, die ich in meiner WPF-App haben möchte.

Meine Frage lautet also: Wie kann ich die Leistung von FlowDocumentScrollViewer an die Leistung von Windows Forms RichTextBox anpassen, ohne Formatierungsfunktionen wie Fettschrift und Kursivschrift zu verlieren und ohne die Kopier- / Einfügefunktionalität zu verlieren? Ich bin bereit, WPF-Steuerelemente zu wechseln, solange sie die Formatierungsfunktionen bieten, die ich suche.

Hier ist mein Druckcode, als Referenz:

%Vor%

Ich wechsle Schriftgrößen und mache Text fett, wenn "wichtiger" Text gedruckt wird. Der Grund, warum dieser Code so viele Zeilen enthält, liegt darin, dass ich versuche, den gleichen Absatz für den gesamten Text wiederzuverwenden, bis ich auf "wichtigen" Text stoße. Ich füge einen neuen Absatz mit dem ganzen "wichtigen" Text hinzu, füge dann einen weiteren Absatz hinzu, sobald ich zu dem unwichtigen Text zurückwechsle und an diesen Absatz anschließe, bis ich mehr "wichtigen" Text treffe. Ich hatte gehofft, dass die Wiederverwendung desselben Absatzes die Leistung verbessern würde.

Es sollte auch angemerkt werden, dass ich stdout zu einem FlowDocumentScrollViewer , stderr zu einem anderen FlowDocumentScrollViewer und beide gleichzeitig zu einem dritten FlowDocumentScrollViewer drucke. Also wird jede Zeile von stdout und stderr technisch zweimal gedruckt, was die Belastung meiner App verdoppelt. Auch dies war in WinForms kein Problem.

Im Folgenden finden Sie ein vollständiges Codebeispiel, wie in den Kommentaren gefordert. Es ist extrem einfach (3 FlowDocumentScrollViewer und einfaches Drucken), aber immer noch verlangsamt sich um rund 20000 Zeilen Text, und viel schlimmer darüber hinaus.

EDIT: Das Codebeispiel wurde entfernt. An seiner Stelle ist der Arbeitscode, um meine Leistungsprobleme zu lösen. Es funktioniert genauso wie FlowDocumentScrollViewer , mit einer Ausnahme: Sie können keine Teilstrings von Linien auswählen. Ich versuche das zu beheben, obwohl es schwierig scheint.

Bridge.cs

%Vor%

MainWindow.xaml

%Vor%

MainWindow.xaml.cs

%Vor%

ListBoxSelector.cs ist in @ Pushprajs Antwort.

    
Darkhydro 30.07.2014, 18:19
quelle

2 Antworten

5

Ich führe das von Ihnen gelieferte Beispiel aus, abgesehen von einigen Threading-Problemen ist das größte Problem die Menge an Daten. was das Text-Rendering verlangsamt, wenn es wächst.

Ich habe versucht, deinen Code anders zu schreiben. Ich habe Tasks, BlockingCollection und Virtualization verwendet, um die Leistung mit Annahmen zu verbessern, die vor allem von der Geschwindigkeit der Protokollierung abhängen.

Bridge.cs

%Vor%

MainWindow.xaml

%Vor%

MainWindow.xaml.cs

%Vor%

Laden Sie für ein voll funktionsfähiges Beispiel PerformanceTest.zip herunter, und prüfen Sie, ob dies in der Nähe ist zu was du brauchst. Ich habe nur einen Teil neu geschrieben. Wenn dieses Beispiel in die gewünschte Richtung führt, können wir den Rest der Funktionalität implementieren. un-comment Task.Delay(1).Wait(); in Bridge.cs, wenn Sie die Produktion verlangsamen möchten, um die gemischten Protokolle zu sehen, andernfalls ist die Protokollgenerierung zu schnell, so dass sie nacheinander in den Protokollen erscheint.

    
pushpraj 23.08.2014, 10:36
quelle
0

Durch die Verwendung von FlowDocumentPageViewer wird die Leistung verbessert, da das Dokument asynchron geladen wird .

    
Ekk 23.08.2014 02:54
quelle

Tags und Links