Das Speichern von .NET-Benutzereinstellungen dauert sehr lange

9

In unserer .NET 4.0 Winforms-Anwendung haben einige Benutzer (alle Win7 x64) kürzlich sehr lange Wartezeiten (im Vergleich zu anderen) erlebt, wenn die Anwendung ihre Einstellungen unter Verwendung dieses Codes speichert:

%Vor%
  • Typische Dauer: 0,5 bis 1 Sekunden
  • Extreme Dauer: 15 bis 20 Sekunden

Die Anwendungseinstellungen (Bereich: Benutzer, alles in user.config unter AppData \ Local \ gespeichert) bestehen aus mehreren benutzerdefinierten Klassen sowie zwei Klassen für Druckereinstellungen: System.Drawing.Printing.PageSettings und System.Drawing.Printing.PrinterSettings

Mit dem GlowCode Profiler auf einer dieser Maschinen fand ich die folgende Funktion für 17 Sekunden:

%Vor%

Davon wurde die Dauer fast gleichmäßig auf drei Getter aufgeteilt (aus dem GlowCode-Viewer):

  • Druckereinstellungen :: get_PaperSizes
  • Druckereinstellungen :: get_PaperSources
  • PrinterSettings :: get_PrinterResolutions

Durch Recherchen ergaben sich folgende Seiten: Ссылка und Ссылка , Zitat:

  

Auf einigen Systemen, insbesondere Vista x64-Systemen, dauert es ewig (5 bis 15)   Sekunden, wenn für x64 kompiliert, 10-20 Sekunden, wenn für x86 kompiliert) aufzuzählen   entweder die PaperSources oder PaperSize-Auflistung eines printersettings-Objekts.

Die Verwendung einer kleinen Test-App, die nur PrinterSettings speichert, ergab auf einer dieser "langsamen" Maschinen eine Einsparung von etwa 3,5 Sekunden, während die andere mit einer Dauer von 0,2 Sekunden nicht beeindruckt war, was meiner schnellen Entwicklungsmaschine entspricht. p>

Irgendwelche Ideen zu den Gründen und wie man das verbessert?

Wie kann ich die wahren Gründe für diese Verzögerungen finden?

Bearbeiten: Danke, dass Sie darauf hingewiesen haben, dass die Druckereinstellungen über den Treiber abgerufen werden. Dies könnte Verzögerungen auf bestimmten Computern erklären.

Das Aktualisieren der Druckertreiber auf Rechnern, auf die ich zukünftig nicht mehr zugreifen kann, wo diese installiert werden, ist nicht möglich.

Ich werde auch nicht (ich weiß, dass ich weiß) die zu speichernden PrinterSettings-Informationen reduzieren, nur weil einige Leute möglicherweise eine Verzögerung erfahren und die Rückwärtskompatibilität eventuell ausbremsen ...

Wenn ich die Serialisierung im Hintergrund versuche (nachdem der Benutzer einige Änderungen am Drucker vorgenommen hat?), könnte es die Dinge beschleunigen ...

    
bettwäsh 18.11.2014, 14:05
quelle

2 Antworten

1

Erster Vorschlag:

Die Anrufe zum Abrufen von Papierquellen und Papierformaten werden an den Treiber weitergeleitet. Am besten stellen Sie sicher, dass die neueste Version des Treibers installiert ist. Es ist möglich, dass ältere Versionen des Treibers (insbesondere die von der CD, die in der Box enthalten ist) alt und fehlerhaft sind. Wenn Sie es noch nicht getan haben, klicken Sie auf die Website des Herstellers und wählen Sie die neueste Version.

Zweiter Vorschlag

Abgesehen davon wird es ein Problem sein, aber Sie könnten versuchen, die zugrunde liegenden Win32-APIs anstelle der CLR-Gegenstücke zu verwenden. In diesem Fall rufen Sie GetPrinter , eine PRINTER_INFO_2 -Struktur anfordern. Sobald Sie das haben, können Sie pDevMode untersuchen, um ein zu erhalten DEVMODE Struktur, die alle Informationen enthält, die Sie suchen.

Diese Frage oder Diese Frage sollte hilfreich sein.

Anstatt die gesamte PrinterSettings-Klasseninstanz beizubehalten, werden nur einzelne Einstellungen als Basistypen beibehalten. Halten Sie es einfach - Strings, Ints, Bools, usw. Der Serializer fordert eindeutig die Kommunikation mit dem Drucker an, und das ist die Einführung der Latenz. Ich bin bereit zu wetten, dass, wenn Sie einzelne Klassenmitglieder ergreifen und sie selbst serialisieren, Sie eine Verbesserung sehen werden.

Offensichtlich bedeutet dies, dass Sie beim Laden der Einstellungen alle diese Einstellungen in eine neue PrinterSettings-Klasse deserialisieren und anwenden müssen.

EDIT 1, als Antwort auf die Frage bearbeiten

Das stimmt - Sie könnten das Save() async im Hintergrund laufen lassen. Ihr einziges Problem wäre, wenn der Benutzer versucht, den Prozess zu beenden (die App zu schließen), bevor der Speichervorgang abgeschlossen ist. Sie müssen einen Bool angeben, ob ein Speichervorgang ausgeführt wird (auf "false" gesetzt, wenn der Rückruf ausgelöst wird). Wenn der Benutzer versucht, die App zu beenden, und der Bool-Wert wahr ist, legen Sie bitte "Bitte warten Sie, während die Einstellungen gespeichert werden ..." auf, bis der Bool-Wert falsch ist.

    
Lynn Crumbling 18.11.2014 14:22
quelle
0

Es scheint also so, als würden einige Maschinen lange Zeit die Seiten- und Druckereinstellungen über den installierten Treiber abfragen. Ich konnte keine weiteren Einzelheiten dazu finden.

Um die Abschaltzeit zu verkürzen, werden die oben genannten Teile der Einstellungen in einem Hintergrund-Thread zugewiesen und gespeichert , nachdem der Benutzer Änderungen an den Druckereinstellungen vorgenommen hat. Das dauert etwa 10 Sekunden.

Beim Herunterfahren (Schließen des Formulars) werden diese Einstellungen nicht erneut zugewiesen, aber wir speichern alle noch (unter Verwendung von Properties.Settings.Default.Save ()) und irgendwie erkennt der Serialisierer, dass dies nicht der Fall ist haben Änderungen an Abfrage und so das Speichern sehr schnell beendet:

Zwischen 0,02 und 0,05 Sekunden, aber trotzdem sind alle Einstellungen richtig gespeichert!

Fun fact: Dieses Problem wurde erstmals in der Woche gemeldet, als wir einen neuen Bürodrucker bekamen:)

    
bettwäsh 19.11.2014 15:47
quelle

Tags und Links