Das Problem:
Lange laufende Datenbankvorgänge können Ihr Hauptanwendungsfenster einfrieren und dazu führen, dass der Fortschrittsbalken nicht mehr reagiert. Dies geschieht, weil die Datenbankaufgabe den Haupt-UI-Thread blockiert.
BackgroundWorker und Multithreading:
Die BackgroundWorker
-Klasse bietet eine Lösung, indem sie langwierige Aufgaben in einen separaten Thread verlagert und so die Reaktionsfähigkeit der Benutzeroberfläche erhält. Allerdings ist die korrekte Verwaltung von UI-Updates aus diesem Hintergrundthread von entscheidender Bedeutung.
Sicheres Aktualisieren der Benutzeroberfläche:
Das Ändern von UI-Elementen erfordert die Verwendung des Dispatchers des Hauptthreads. Das direkte Aktualisieren von UI-Steuerelementen aus einem Hintergrundthread ist unsicher und führt zu Fehlern.
Die Lösung:
Um das Einfrierproblem zu lösen, verwenden Sie ein spezielles BackgroundWorker
ausschließlich für Fortschrittsbalkenaktualisierungen. Dies hält den Datenbankbetriebsarbeiter getrennt und verhindert Konflikte.
Code-Implementierung:
MainWindow.xaml: Entfernen Sie alle Versuche, den Fortschrittsbalken direkt im BackgroundWorker
des Datenbankvorgangs zu aktualisieren.
Dedizierter Fortschrittsbalken-Mitarbeiter: Erstellen Sie eine neue Klasse, um Fortschrittsbalken-Updates zu verwalten:
<code class="language-csharp">public class ProgressBarWorker { private ProgressBar progressBar; private BackgroundWorker worker; public ProgressBarWorker(ProgressBar progressBar) { this.progressBar = progressBar; worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += Work; worker.ProgressChanged += ProgressChanged; // Added ProgressChanged handler } public void Run() { worker.RunWorkerAsync(); } private void Work(object sender, DoWorkEventArgs e) { // Simulate long-running work; replace with your database operation for (int i = 0; i < 100; i++) { Thread.Sleep(100); // Simulate work worker.ReportProgress(i); // Report progress to the main thread } } private void ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; // Update progress bar on main thread } }</code>
MainWindow-Code (Beispiel): Initialisieren und starten Sie in Ihrem UserControl_Loaded
-Ereignis das ProgressBarWorker
:
<code class="language-csharp">ProgressBarWorker progressBarWorker = new ProgressBarWorker(progressBar); progressBarWorker.Run();</code>
Vorteile:
Das obige ist der detaillierte Inhalt vonWie kann ein Einfrieren der Benutzeroberfläche verhindert werden, wenn BackgroundWorker für Datenbankvorgänge mit langer Laufzeit verwendet werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!