2017-03-07 4 views
0

nicht aktualisiert Ich habe den folgenden Code:Etikett in WPF-Anwendung

label1.content = "Start"; 
bool a = executeLongTask(); 
label1.content = "Done"; 

Aus irgendeinem Grunde nur das Etikett aktualisiert wird auf „Fertig“, nachdem der executeLongTask() -Methode abgeschlossen ist. Es überspringt vollständig die Anzeige "Start".

Warum wird das Label nicht auf "Start" gesetzt, wenn die Anwendung ausgeführt wird, und wie würde ich es auf "Start" aktualisieren, ohne zuerst mehrere Threads zu verwenden?

Die executeLongTask() -Methode ruft übrigens ein PowerShell-Skript auf und wartet darauf, dass es ausgegeben wird, bevor es weitergeht label1.content = "Done";

Antwort

3

Aus irgendeinem Grund wird die Beschriftung erst auf "Done" aktualisiert, nachdem die executeLongTask() - Methode abgeschlossen wurde. Es überspringt vollständig die Anzeige "Start".

Das ist, weil der UI-Thread zu seiner Hauptschleife zurückkehren muss, um WM_PAINT Updates zu verarbeiten. Wenn Sie das Label zum ersten Mal festlegen, merkt WPF, dass es das Label neu zeichnen soll, wenn es in die Nachrichtenverarbeitungsschleife zurückkehrt. Dann wird die Benutzeroberfläche in der executeLongTask-Methode beschäftigt, und dann wird die Beschriftung das zweite Mal festgelegt, und WPF merkt erneut, dass es die Beschriftung neu zeichnen sollte. Wenn Sie die Steuerung an die UI-Nachrichtenschleife zurückgeben, erhält sie schließlich die Möglichkeit, das Bild neu zu zeichnen und zu aktualisieren, was Sie auf dem Bildschirm sehen.

Wie würde ich es zuerst auf "Start" aktualisieren lassen, ohne mehrere Threads zu verwenden?

Die einfachste Lösung ist, mehrere Threads zu verwenden. Beispiel:

label1.content = "Start"; 
bool a = await Task.Run(() => executeLongTask()); 
label1.content = "Done"; 

Alternativ könnten Sie executeLongTask umschreiben asynchron zu handeln, und dann würden Sie nicht einen separaten Thread benötigen:

label1.content = "Start"; 
bool a = await executeLongTaskAsync(); 
label1.content = "Done"; 
+0

Vielen Dank für Ihren ausführlichen und informativen Beitrag. Mir ist nicht aufgefallen, dass WPF das zu aktualisierende Label notiert und es dann tatsächlich setzt, wenn es von der Methode zurückkommt. So war ich verwirrt, warum es nicht einfach das erste Etikett setzen, die lange Ausführung durchführen und dann das letzte Etikett setzen kann. Nochmals vielen Dank, ich denke, ich werde mit der ersten Lösung gehen, die Sie zur Verfügung gestellt haben. – John

1

Der Text wird erst aktualisiert, wenn die Funktion zurückkehrt. Wenn Sie möchten, dass es aktualisiert wird, während executeLongTask() ausgeführt wird, müssen Sie das async/await Muster verwenden. Mit dieser Option können Sie die Kontrolle zurückgeben, bis die lange Aufgabe abgeschlossen ist.