geht hier zwei Links versuchen, Ihnen zu erklären, wie die Dinge funktionieren: (1)(2)
Nun, ich werde versuchen, es zu erklären, so kurz wie ich kann. Das meiste, was in einer Windows Forms-Anwendung passiert, geschieht in einem einzigen Thread, normalerweise im selben Thread, in dem Main() ausgeführt wird. Wenn Sie Program.cs öffnen, sehen Sie, dass Main() eine Zeile hat, die wie folgt aussieht:
Wenn Sie die Anwendung zu jedem beliebigen Zeitpunkt debuggen und den Aufruf-Stapel untersuchen, werden Sie feststellen, dass es auf diese Run-Methode zurückverfolgt wird. Dies bedeutet, dass eine Windows Forms-Anwendung tatsächlich eine fortlaufende Ausführung der Run-Methode ist. Also, was macht Run? Run isst eine Nachrichtenwarteschlange, über die Windows Nachrichten an sie sendet. Run sendet dann diese Nachrichten an die richtigen Steuerelemente, die selbst Dinge wie das Hinzufügen von Text zum gedrückten Schlüssel, Neuzeichnen usw. vornehmen. Beachten Sie, dass dies alles während und während der Endlosschleife neben einem einzelnen Thread ausgeführt wird, also wenn Sie gerade tippen oder einfach das Fenster herum bewegen, viele dieser Nachrichten werden an die Anwendung weitergegeben, die wiederum sie verarbeitet und entsprechend reagiert, alles in diesem einzelnen Thread. Controls können über die Warteschlange auch Nachrichten an sich selbst senden und sogar über Control.BeginInvoke können Sie Nachrichten in der Pumpe platzieren. Eine der Sachen, die diese Kontrollen tun, ist Ereignisse entsprechend dem, was passiert, auszulösen. Wenn Sie also auf eine Schaltfläche klicken, wird der Code, den Sie für diesen Klick geschrieben haben, letztendlich und indirekt von der Application.Run-Methode ausgeführt.
Nun, was passiert mit Ihrem Code ist, dass, obwohl Sie den sichtbaren Status Ihrer Fortschrittsbalken zu sichtbar ändern und dann aktualisieren Sie den Wert, Sie ändern dann seine Sichtbarkeit in false, alle in der gleichen Methode. Das bedeutet, dass Application.Run() erst nach dem Verlassen der Methode fortfahren kann, die Nachrichtenwarteschlange zu durchlaufen und zu konsumieren, wodurch der Fortschrittsbalken aufgefordert wird, seine Anzeige zu aktualisieren. Wenn dies geschieht, haben Sie die Sichtbarkeit der Fortschrittsleiste bereits auf "Falsch" gesetzt, das letzte, was Sie vor dem Beenden der Methode getan haben. DoEvents() ist eine schnelle und schmutzige Lösung für Ihr Problem, wie es die Nachrichten in der Warteschlange liest und verarbeitet. Ich fühle mich nicht wohl dabei, es zu benutzen, da es Probleme mit der Wiedereintrittsfähigkeit bringt.
Verwenden von Threads ist eine gute Lösung, aber ich würde empfehlen, einen ThreadPool-Thread anstelle eines benutzerdefinierten Threads in einer solchen Situation zu verwenden, da ich benutzerdefinierte Threads nur in Fällen verwende, in denen ich eine begrenzte Anzahl von langlebigen Threads habe und ich muss ihre Lebenszyklen kontrollieren. Die einfachste und praktischste Methode zum Verwenden von Threads ist die Verwendung der BackgroundWorker-Komponente, obwohl ich Ihnen empfehlen würde, sich mit dem Delegieren von Windows Forms-Multithreading vertraut zu machen, wenn Sie wirklich verstehen wollen, was vor sich geht.
Ich nehme an, Sie empfehlen, den langen laufenden Prozess zu einem separaten Thread zu bewegen, die Benutzeroberfläche nutzbar jederzeit korrekt zu halten? –
Ja - das macht BackgroundWorker einfach. –
Schätzen Sie die Hilfe. Ich hatte gehofft, Threads zu vermeiden, da sie manuell ziemlich schwierig sind und das ist eine einfache Benutzeroberfläche, aber das klingt perfekt. Vielen Dank. –