Multithreading problem

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von mrMo.

    Multithreading problem

    Hallo zusammen.

    Ich habe ein Problem mit Multithreading wenn ich ein Sub aus einem Modul aufrufe. Ich starte den Thread via Button aus meiner Form. Die Sub liegt wie gesagt in einem separatem Modul.

    Aufruf:

    VB.NET-Quellcode

    1. backupThread = New Thread(AddressOf backupProcess)
    2. backupThread.Start()



    Sub:

    VB.NET-Quellcode

    1. Public Sub backupProcess()
    2. list = New List(Of String)
    3. Dim currentFilename As String
    4. Dim subDirectory As String = ""
    5. Dim lastModifiedBackup As DateTime
    6. Dim lastModifiedDestination As DateTime
    7. Dim fileCount As Long = 0
    8. Dim copyCounter As Long = 0
    9. Dim changeCounter As Long = 0
    10. Dim errorCounter As Long = 0
    11. Form1.copyList.Items.Clear()
    12. Form1.BackupProgress.Value = 0
    13. Dim directoryList As String() = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories)
    14. list = directoryList.ToList
    15. StartCopy:
    16. fileCount = Directory.GetFiles(sourcePath & subDirectory).Count
    17. Form1.BackupProgress.Maximum = fileCount
    18. For Each file In IO.Directory.GetFiles(sourcePath & subDirectory)
    19. currentFilename = Path.GetFileName(file)
    20. If Not IO.File.Exists(destinationPath & subDirectory & currentFilename) Then
    21. Try
    22. IO.File.Copy(sourcePath & subDirectory & currentFilename, destinationPath & subDirectory & currentFilename)
    23. Form1.copyList.Items.Add(DateTime.Now & ": " & "\" & subDirectory & currentFilename)
    24. Form1.copyList.Update()
    25. Form1.copyList.TopIndex = Form1.copyList.Items.Count - 1
    26. copyCounter += 1
    27. Catch ex As Exception
    28. errorCounter += 1
    29. End Try
    30. Else
    31. lastModifiedBackup = IO.File.GetLastWriteTime(sourcePath & subDirectory & currentFilename).ToUniversalTime
    32. lastModifiedDestination = IO.File.GetLastWriteTime(destinationPath & subDirectory & currentFilename).ToUniversalTime()
    33. If lastModifiedBackup > lastModifiedDestination Then
    34. Try
    35. IO.File.Copy(sourcePath & subDirectory & currentFilename, destinationPath & subDirectory & currentFilename, True)
    36. Form1.copyList.Items.Add(DateTime.Now & ": " & "\" & subDirectory & currentFilename & " - change")
    37. Form1.copyList.Update()
    38. Form1.copyList.TopIndex = Form1.copyList.Items.Count - 1
    39. changeCounter += 1
    40. Catch ex As Exception
    41. errorCounter += 1
    42. End Try
    43. End If
    44. End If
    45. If Not Form1.BackupProgress.Value = Form1.BackupProgress.Maximum Then Form1.BackupProgress.Value += 1
    46. Next
    47. For Each item In list
    48. Dim dirInfo As New System.IO.DirectoryInfo(item)
    49. subDirectory = dirInfo.FullName.ToString().Replace(sourcePath, "") & "\"
    50. If Not Directory.Exists(destinationPath & subDirectory) Then Directory.CreateDirectory(destinationPath & subDirectory)
    51. list.RemoveAt(0)
    52. GoTo StartCopy
    53. Next
    54. endTime = DateTime.Now
    55. duration = (endTime - startTime).TotalSeconds
    56. ts = TimeSpan.FromSeconds(duration)
    57. With Form1
    58. .copyList.Items.Add("")
    59. .copyList.Items.Add("Files copied: " & copyCounter & " - " & "Files changed: " & changeCounter & " - " & "Errors: " & errorCounter)
    60. .copyList.Items.Add("Duration: " & ts.ToString)
    61. .BackupProgress.Value = fileCount
    62. End With
    63. Form1.copyList.TopIndex = Form1.copyList.Items.Count - 1
    64. BackupOffState()
    65. writeLogFile()
    66. End Sub



    Das Problem ist, es funktioniert zwar, heißt die Dateien werden alle kopiert und alles aber es wird die Listbox nicht befüllt, die Progressbar funktioniert nicht und das ganze hängt nach dem End Sub.


    Weiß jemand eine Lösung?
    Wo ist Form1 deklariert? Vermutlich nirgends und vor allem auch nicht instanziert.

    Und schmeiß zum Debuggen alle Try/Catch Blöcke raus.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Alle Control Elemente tu ich in einem Thread mit

    VB.NET-Quellcode

    1. ​ BeginInvoke(Sub())
    versehen

    also zum Beispiel Statt:

    dr. Nick schrieb:

    Form1.copyList.Items.Add(DateTime.Now & ": " & "\" & subDirectory & currentFilename & " - change")


    VB.NET-Quellcode

    1. BeginInvoke(Sub()Form1.copyList.Items.Add(DateTime.Now & ": " & "\" & subDirectory & currentFilename & " - change"))​

    (nicht getestet, hat aber bei mir Geholfen)

    Nebenbei bemerkt: Ich vermisse im Code die Zeile CheckForIllegalCrossThreadCalls = True, denn ohne sie würde der Code nicht gehen. Was natürlich auch bedeutet, dass der ganze Code so ein no go ist. Vom GoTo in Zeile#69 mal ganz abgesehen.
    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.

    Morrison schrieb:

    VB.NET-Quellcode

    1. Form1.BackupProgress.Invoke(Sub() Form1.BackupProgress.Value += 1)
    Klappt wahrscheinlich, es ist möglicherweise die falsche Instanz, wohl aber derselbe Thread.
    Dialoge: Instanziierung von Forms und Aufruf von Dialogen
    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!
    Vollzitat eines Vorposts durch Anredefunktion ersetzt ~VaporiZed
    @VaporiZed:
    Was genau stimmt mit dem GoTo nicht? Ich meine, ja man könnte alles in eine Schleife packen und Goto stammt glaube ich noch von Q-Basic aber warum soll man das genau heute nicht mehr verwenden?

    BG

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    mrMo schrieb:

    Wo ist Form1 deklariert? Vermutlich nirgends und vor allem auch nicht instanziert.
    Dieselbe Vermutung habe ich auch.
    Da wird sich auf den alten VB6-Mechanismus der automatischen Instanziierung verlassen, was natürlich schief geht.
    Dialoge: Instanziierung von Forms und Aufruf von Dialogen
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    Dieselbe Vermutung habe ich auch.
    Ja. Und @RodFromGermany hat diese Vermutung ebenso. Aber leider scheint @dr. Nick das zu ignorieren...
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen