c# progressbar nicht aktualisiert
Ich habe eine ProgressBarWindow die eine progressbar und eine Abbrechen-Schaltfläche, die ich nutzen, um Fortschritte auf Datei-I/O. Jedoch im UI-Thread der ProgressBarWindow und mein Hauptfenster beide hängen trotz all der Arbeit in einem backgroundworker. Die progressbar dargestellt wird, als ist mein main-Fenster, aber nicht aktualisiert, während der backgroundworker seine Sache macht.
Der folgende code aufgerufen wird am Ende der Konstruktor des Hauptfensters:
iCountLogLinesProgressBar = new ProgressBarWindow();
iCountLogLinesProgressBar.cancelButton.Click += EventCountLogLinesProgressBarCancelButtonClicked;
iCountLogLinesProgressBar.Show();
iCountLogRecords = new BackgroundWorker();
iCountLogRecords.DoWork += EventCountLogLinesDoWork;
iCountLogRecords.ProgressChanged += EventCountLogLinesProgressChanged;
iCountLogRecords.RunWorkerCompleted += EventCountLogLinesRunWorkerCompleted;
iCountLogRecords.WorkerReportsProgress = true;
iCountLogRecords.WorkerSupportsCancellation = true;
iCountLogRecords.RunWorkerAsync(new BinaryReader(File.Open(iMainLogFilename, FileMode.Open, FileAccess.Read)));
EventCountLogLinesProgressChanged() sieht wie folgt aus:
private void EventCountLogLinesProgressChanged(object sender, ProgressChangedEventArgs e)
{
iCountLogLinesProgressBar.Value = e.ProgressPercentage;
}
Hier ist eine verkürzte version von ProgressBarWindow(der rest ist nur ein paar setter):
public partial class ProgressBarWindow : Window
{
public ProgressBarWindow()
{
InitializeComponent();
this.progressBar.Value = this.progressBar.Minimum = 0;
this.progressBar.Maximum = 100;
}
public double Value
{
get
{
return progressBar.Value;
}
set
{
this.progressBar.Value = value;
}
}
}
Habe ich versucht, das einwickeln der Wert setter-Linie in einen dispatcher.aufrufen delegieren, aber das gibt mir ein stack-overflow(ich sollte nicht zu haben, einen dispatcher.invoke-Linie eh als backgroundworker ruft ProgressChanged in der UI-Thread, richtig?). Ich habe in msdn und gegoogelt, aber ich kann nicht scheinen, um herauszufinden, jemand anderes mit diesem problem.
BEARBEITEN Entschuldigung, ich wusste nicht, mein vereinfachter code blockiert den UI Thread, bekomme ich genau das gleiche Verhalten, ungeachtet einer mit einem backgroundworker, so dass ich irrtümlich davon ausgegangen, dass Sie gleichwertig waren. Ich sollte erwähnt haben, dass ich mit einem backgroundworker 😛
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du bist die Blockierung der UI-thread, damit es nicht erneut Rendern der UI, bis die Schleife beendet wurde.
Bewegen Sie die hintergrund-Verarbeitung in einem separaten thread, und verwenden Sie geeignete
Dispatcher
Anrufe (oderBackgroundWorker
) Marschall UI-update-Aufrufe zurück an den UI-thread.Wenn Ihr Fortschritt wird wirklich einfach sein soll, einen timer, Sie könnte verwenden Sie eine der
Timer
Klassen zu aktualisieren.EDIT: Okay, jetzt hast du den code veränderte, es sieht okay für mich. Es sollte thread-sicher, da Sie nur die änderung der UI im UI-thread. Ist dein background worker definitiv Berichterstattung über die Fortschritte in regelmäßigen Abständen?
Hören Jon Skeet,
oder man könnte manchmal rufen die Anwendung.DoEvents (), damit alle UI-updates in den gleichen thread.
Application.DoEvents()
! Es ist nur im Rahmen und für die rückwärts-Kompatibilität mit VB6. Es ist eine großartige Möglichkeit, um die Einführung von Fehlern im code.