Backgroundworker Abbruch

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 78 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Backgroundworker Abbruch

    Hey moin moin

    Ich habe in meinem Tool eine Kopierfunktion mit dem Backgroundworker, was auch alles klappt.
    Nun habe ich des mit dem Abbrechen versucht mit einzucoden.

    WorkerReport & WorkerSupportsCancel... sind beide auf True

    Der Prozess wird aber nicht unterbrochen.. wo steckt der Fehler?

    VB.NET-Quellcode

    1. Private Sub btn_cancel_Click(sender As Object, e As EventArgs) Handles btn_cancel.Click
    2. BackgroundWorker1.CancelAsync()
    3. 'BackgroundWorker2.CancelAsync()
    4. 'btn_cancel.Enabled = False
    5. End Sub
    6. Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    7. Try
    8. If mstrVZip = Nothing Then
    9. BackgroundWorker1.ReportProgress(100)
    10. My.Computer.FileSystem.CopyDirectory(Main.Source, mstrTargetdir)
    11. If BackgroundWorker1.CancellationPending = True Then
    12. e.Cancel = True
    13. Exit Try
    14. End If
    15. Else
    16. BackgroundWorker1.ReportProgress(100)
    17. IO.Directory.CreateDirectory(mstrTargetdir)
    18. ZipFile.CreateFromDirectory(Main.Source, mstrTargetdir & ".zip", CompressionLevel.Optimal, False)
    19. If BackgroundWorker1.CancellationPending = True Then
    20. e.Cancel = True
    21. Exit Try
    22. End If
    23. End If
    24. Catch ex As Exception
    25. MessageBox.Show("Fehler: " & ex.ToString)
    26. End Try
    27. End Sub
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @Amelie Ein BGW ist auch nur ein Thread.
    Üblicherweise läuft in einem Thread eine Endlosschleife, die bei Bedarf etwas tut.
    Bei einem Abbruch wird die Schleife verlassen uns feddich.
    Du hast keine Schleife, also kann nix abgebrochen werden.
    Wenn Du 100 Dateien zippen willst, darfst Du nach einem Break das Zippen der nächsten Datei nicht beginnen.
    Wenn da nur eine Datei betroffen ist, müsstest Du Deine ZipFile-Befehle abwürgen, wenn er da drinne beschäftigt ist.
    Ob das möglich ist, weiß ich nicht.
    Wie sieht Dein Gesamtablauf aus?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Gesammtablauf? ..
    Also ich bestimmt mittels OpenDialog Quelle, Ziel welche in Variablen abgelegt werden aber zusätzlich auch in den Settings des Tools, damit ich diese nicht ständig neu eingeben muss. Weil, zu 90% ändert sich an der Quelle nichts, immer ein USB-Stick mit gleichen Verzeichniss, nur die Dateien sind neuer.

    Vor dem Kopieren kann ich noch mittels Radiobutton auswählen ob nur Kopieren oder gleich das Verzeichnis gezipet werden soll. Das klappt auch alles so wie es soll.
    Nur der Abbruch klappt nicht.

    VB.NET-Quellcode

    1. ' Hier werden vorher nur einige Angaben geprüft, ob Ziel und Quelle eingegeben sind usw..
    2. .......
    3. Else
    4. btn_copy.Enabled = False
    5. btn_close.Enabled = False
    6. btn_edit.Enabled = False
    7. BackgroundWorker1.RunWorkerAsync()
    8. 'BackgroundWorker2.RunWorkerAsync()
    9. End If
    10. Catch ex As Exception
    11. MessageBox.Show("Fehler: " & ex.ToString)
    12. End Try
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Nur der Abbruch klappt nicht.
    Was ganz genau soll abgebrochen werden?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Eben das Kopieren oder Zippen ....
    Eigentlich bräuchte ich das nicht aber in vielen Tutorials etc steht immer das eine Möglichkeit des abbrechen eines Prozess sauber wäre.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    das Kopieren oder Zippen
    von einer Datei oder von mehreren Dateien?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Amelie Wie lange dauert das Zippen einer Datei?
    Höre auf, die nächste Datei zu zippen, wenn Break kommt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Amelie schrieb:

    Es wird aber der komplette Ordner gezippt.
    Dann musst Du entweder die Dateien einzeln zippen, um den Abbruch zu organisieren oder die ZipFile-Prozedur abwürgen, davon muss ich Dir sehr abraten, weil da "Datei-Leichen" übrig bleiben könnten, die nur schwer aufzuräumen sind.
    Wenn Du statt eines BGW einen "richtigen" Thread instanzieren würdest, könntest Du den mit .Abort() mit Gewalt beenden, was aber nicht Sinn der Sache ist.
    ====
    Also wenn ich mir das genau überlege, ist ein Einzel-Datei-Handling mit Abfrage des Abbruch-Flags nach jeder Datei der beste Weg.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wohl nicht. ;)
    Betrachte es einfach als Fingerübung.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wenn du selber schon sagst, dass du es eigentlich nicht brauchst dann lass es lieber.
    Wie @RodFromGermany schon sagte müsstest du bei sowas in Einzelschritten vorgehen und dann bleiben ohne Ende Leichen zurück. Die müsstest du dann auch noch bereinigen. Das macht alles mehr Arbeit als es Sinn bringt.
    Aus eigener Erfahrung war sowas immer der Punkt bei dem ein zweiter auf mein Projekt geschaut hat und fragte ob das wirklich sein muss, denn eigentlich ist man schon fertig wenn man mit sowas nochmal anfängt.
    Also mein Rat lass es lieber.
    Wenn ein User einen Prozess startet dann will er es auch und will es eigentlich nicht abbrechen. Dann lieber danach eine Routine zum rückgängig machen, das ist bei weitem einfacher
    @ThomasG82
    Da hast du wohl Recht ;)

    Ein kleines Problem habe ich dennoch.

    Ich öffne eine form und diese soll nach Beendigung des BGW wieder geschlossen werden.. aber das wird sie nicht.

    VB.NET-Quellcode

    1. Public Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    2. frmcopy.Timer1.Stop()
    3. frmcopy.Close() ' <======== Die soll geschlossen werden, geht nicht ABER
    4. Dim übergabe As String = "fertig"
    5. Using frm As New frm_message(übergabe) '<====== Diese wird geöffnet!!!
    6. frm.ShowDialog(Me)
    7. End Using
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Auch wenn ein bisschen zu wenig Info da ist (v.a. was frmcopy genau ist), spekulationiere ich auf: Da der BGW nicht im Hauptthread ist, ist frmcopy "innerhalb" des BGW was anderes als außerhalb. Hier nachzulesen: Warum »Form1.Show« und Co. einem irgendwann ins Bein schießen
    Aber frm wird "innerhalb" des BGW erzeugt und verhält sich damit so, wie Du es erwartest.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Amelie Lässt Du uns an Deinem Erfolg teilhaben?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich weiß nicht ob das der Mühe wert ist

    So aufwendig ist das nicht. Öffne ein Zip Archiv, hol dir alle Dateien die du verpacken willst, durchlauf das Array mit einer Schleife und pack den String ins Archiv. Als Abbruchbedingung nimmst du das System.Threading.CancellationToken aus einem System.Threading.CancellationTokenSource.

    Beispiel

    C#-Quellcode

    1. /*
    2. using System.IO;
    3. using System.IO.Compression;
    4. using System.Threading;
    5. */
    6. // Aufruf
    7. CancellationTokenSource cts = new CancellationTokenSource();
    8. ZipDirectory(dirToZip, outputPath, cts.Token);
    9. Thread.Sleep(1000);
    10. cts.Cancel();

    C#-Quellcode

    1. public static void ZipDirectory(string rootDir, string outputFileName, CancellationToken ct)
    2. {
    3. new Thread(() =>
    4. {
    5. ZipArchiveMode mode = File.Exists(outputFileName) ? ZipArchiveMode.Update : ZipArchiveMode.Create;
    6. using (ZipArchive archive = ZipFile.Open(outputFileName, mode))
    7. {
    8. foreach (string file in Directory.GetFiles(rootDir, "*.*", SearchOption.AllDirectories))
    9. {
    10. if (ct.IsCancellationRequested)
    11. break;
    12. string pathRoot = Path.GetPathRoot(file);
    13. string fileName = file.Replace(pathRoot, ""); // Laufwerksbuchstaben entfernen
    14. archive.CreateEntryFromFile(file, fileName);
    15. }
    16. }
    17. }).Start();
    18. }