C# WPF: Backgroundworker mit Progressbar!

Nick_SMI

Ensign
Registriert
Sep. 2015
Beiträge
153
Hallo zusammen!

Ich habe im Internet nicht brauchbare Ergebnisse gefunden, wie ich den Backgroundworker mit einer Progressbar verwende...
Mein Code unten: Wie muss ich vorgehen?

Grüße und danke im Voraus!

Code:
private readonly BackgroundWorker bw2 = new BackgroundWorker();

        void bw2_DoWork(object sender, DoWorkEventArgs e)
        {
            einfuegenOrdner();
        }

        void bw2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }

        void bw2_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            
        }

private void einfuegenOrdner() //Eigentliches einfügen
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                   //Hier wären meine Erledigungen (Invoke wegen des Übergreifens an System.IO
            }
            ));
        }

        private void EinfügenOrdner_Click(object sender, RoutedEventArgs e)
        {
            bw2.WorkerReportsProgress = true;
            bw2.WorkerSupportsCancellation = true;

            bw2.DoWork += new DoWorkEventHandler(bw2_DoWork);
            bw2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw2_RunWorkerCompleted);
            bw2.ProgressChanged += new ProgressChangedEventHandler(bw2_ProgressChanged);

            bw2.RunWorkerAsync();
        }
 
Dann google nochmal oder schau bei Youtube, gibt mehr als genug Guides dafür...
 
Am besten wären hier ViewModels oder zumindest Bindings, wenn du es aber unbedingt per Direktzugriff auf das UI-Element willst, dann ist mit das einfachste wohl das:

Code:
            Task.Run(() =>
            {
                for (var i = 0.0; i < 100; i+=0.1)
                {
                    Thread.Sleep(5); // Dein Code der Parallel ablaufen soll
                    
                    Dispatcher.Invoke(
                        () =>
                        {
                            progressBar.Value = i;
                        });
                }
            });
Du brauchst kein BackgroundWorker, mittlerweile nutzt man für Hintergrundaufgaben einfach die Tasks-Klasse.
 
Zuletzt bearbeitet:
Bagbag schrieb:
Am besten wären hier ViewModels oder zumindest Bindings, wenn du es aber unbedingt per Direktzugriff auf das UI-Element willst, dann ist mit das einfachste wohl das:

Code:
            Task.Run(() =>
            {
                for (var i = 0.0; i < 100; i+=0.1)
                {
                    Thread.Sleep(5); // Dein Code der Parallel ablaufen soll
                    
                    Dispatcher.Invoke(
                        () =>
                        {
                            progressBar.Value = i;
                        });
                }
            });
Du brauchst kein BackgroundWorker, mittlerweile nutzt man für Hintergrundaufgaben einfach die Tasks-Klasse.

Okay, danke!
Wo würde dann mein Code reinkommen, wieder in den Invoke vor oder nach progressBar.Value = i;?
 
In das Invoke kommt alles hinein, was mit dem UI interagiert, außerhalb dann den Rest, was parallel ablaufen soll, ohne dass sich das Programm aufhängt.
Ergänzung ()

Hier mal ein komplettes Beispiel um eine Datei im Hintergrund zu kopieren ohne dass sich das Programm aufhängt und eine ProgressBar den aktuellen Wert anzeigt:

Code:
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                using (FileStream input = new FileStream("file1.bla", FileMode.Open))
                {
                    using (FileStream output = new FileStream("file2.bla", FileMode.Create))
                    {
                        byte[] buffer = new byte[102400];
                        int bytesRead, totalBytesWritten = 0;

                        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, bytesRead);
                            totalBytesWritten += bytesRead;
                            Dispatcher.Invoke(() => progressBar.Value = 1d / input.Length * totalBytesWritten);
                        }
                    }
                }
            });
        }
 
Zuletzt bearbeitet:
Bagbag schrieb:
In das Invoke kommt alles hinein, was mit dem UI interagiert, außerhalb dann den Rest, was parallel ablaufen soll, ohne dass sich das Programm aufhängt.
Ergänzung ()

Hier mal ein komplettes Beispiel um eine Datei im Hintergrund zu kopieren ohne dass sich das Programm aufhängt und eine ProgressBar den aktuellen Wert anzeigt:

Code:
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                using (FileStream input = new FileStream("file1.bla", FileMode.Open))
                {
                    using (FileStream output = new FileStream("file2.bla", FileMode.Create))
                    {
                        byte[] buffer = new byte[102400];
                        int bytesRead, totalBytesWritten = 0;

                        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, bytesRead);
                            totalBytesWritten += bytesRead;
                            Dispatcher.Invoke(() => progressBar.Value = 1d / input.Length * totalBytesWritten);
                        }
                    }
                }
            });
        }

Hat super geklappt, besser als der bw!! Danke :D
 
Zurück
Oben