Dateien Async kopieren

  • VB.NET

Es gibt 80 Antworten in diesem Thema. Der letzte Beitrag () ist von samson.

    Dateien Async kopieren

    Moin Moin Zusammen,

    ich steh mal wieder vor einer kleinen Herausforderung der ich nicht so ganz hinterher komme.
    Leider haben mich die Beiträge im Forum und bei der MSDN nicht weitergebracht, es war mir wohl nicht verständlich genug... Was auch immer :)

    Ich suche eine Möglichkeit Dateien Async von A nach B zu kopieren... (Abzugleichen)
    Mein Aufbau an und für sich klappt ganz gut, nur das Programm was ich mir mit ein paar Zeilen geschrieben habe, bekommt logischerweise "Keine Rückmeldung" bis alles abgeglichen ist.

    Hab nach mehreren stunden Google befragen nun immer wieder gelesen das Async das Problem "behebt"

    Unterm Strich ist mein Quellcode recht einfach

    VB.NET-Quellcode

    1. Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    2. If Directory.Exists(FolderBrowserDialog2.SelectedPath) Then
    3. Directory.CreateDirectory(sPath)
    4. Try
    5. If File.Exists(Destination) Then
    6. TextBox2.AppendText("Datei bereits vorhanden" & Environment.NewLine)
    7. Else
    8. System.IO.File.Copy(source, Destination, True)
    9. TextBox1.AppendText(CStr("\") + lastline & Environment.NewLine)
    10. End If
    11. Catch
    12. If File.Exists(source) Then
    13. TextBox2.AppendText("Konnte nicht kopiert werden: " & CStr("\") + lastline & Environment.NewLine)
    14. Else
    15. TextBox2.AppendText("Nicht gefunden: " & CStr("\") + lastline & Environment.NewLine)
    16. End If
    17. End Try
    18. End If
    19. End Sub


    Die Try und Catch geht,... ok, zugegeben es könnte besser sein, mit Dateigröße abgleichen... Aber das ist mir nicht so wichtig... Um die Dateien um die es da geht, macht mir das nichts aus, wenn mal was "verloren" geht.

    Meine Frage wäre nun, wie bekomme ich das ganze in einen Async Handler?
    Habe schon einiges versucht und auch wieder einiges verworfen...

    Danke und Grüße,
    samson
    Nein! Doch! OHH!
    Von wo kommen denn Source und Destination, werden die eingegeben oder wie werden die bestimmt?
    Um welche Dateien handelt es sich? In deinem Beispiel ist nur von einer Rede, da weiß man nicht, welche Dateien du alle verschieben willst.

    Ich würde die Schleife über alle Dateien vermutlich mit Parallel.ForEach oder Parallel.For lösen.

    Ein direktes Beispiel kann ich dir nicht geben, weil halt einige Informationen fehlen, aber damit würdest du zB. alle Dateien aus dem Ordner parallel bearbeiten:

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Threading.Tasks
    3. Private Sub foo(directory As DirectoryInfo)
    4. Parallel.ForEach(directory.EnumerateFiles(), Function(file) Console.WriteLine(file.FullName) End Function)
    5. End Sub

    @TE: schreib die Methode am besten um in eine Function, der du die nötigen Argumente übergibst, und die dann einen Antwort-String zurückgibt.
    DAnn kann man die Methode mit Leichtigkeit async aufrufen, und im MainThread dann den Antwort-String der Textbox anhängen.

    Also schreib du die Function, dann schreib ich den Umbau nach Async.

    @Counterbug: soweit ich seinen Code verstehe, kopiert er da nur eine einzige bestimmte Datei.
    Ich wüsste nicht, was er da mit Paralell.For gewinnen könnte.
    @ErfinderDesRades
    anbei der komplette kladderadatsch ;)

    VB.NET-Quellcode

    1. Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    2. Button3.Enabled = False
    3. Dim counter As Integer = 0
    4. Dim err_counter As Integer = 0
    5. Dim info_counter As Integer = 0
    6. Dim sFile As String = IO.Path.GetFileName(OpenFileDialog1.FileName)
    7. System.IO.File.Copy(OpenFileDialog1.FileName, FolderBrowserDialog1.SelectedPath + "\" + sFile, True)
    8. If File.Exists(OpenFileDialog1.FileName) Then
    9. TextBox1.AppendText("BDT Datei in Zielverzeichnis kopiert:" & sFile & Environment.NewLine)
    10. End If
    11. For Each line In IO.File.ReadLines(OpenFileDialog1.FileName)
    12. If line.Contains("BRIEFE\") Then
    13. Dim line2 As String = CStr(line)
    14. Dim newline As String = line2.Remove(0, line2.IndexOf("BRIEFE\"))
    15. Dim lastline = newline
    16. Dim source = FolderBrowserDialog2.SelectedPath + CStr("\") + lastline
    17. Dim copyline = FolderBrowserDialog2.SelectedPath + CStr("\") + lastline
    18. Dim Destination As String = FolderBrowserDialog1.SelectedPath + CStr("\") + lastline
    19. Dim sPath As String = FolderBrowserDialog1.SelectedPath + CStr("\") + IO.Path.GetDirectoryName(lastline)
    20. If Directory.Exists(FolderBrowserDialog2.SelectedPath) Then
    21. Directory.CreateDirectory(sPath)
    22. Try
    23. If File.Exists(Destination) Then
    24. TextBox2.AppendText("Datei bereits vorhanden" & Environment.NewLine)
    25. info_counter = info_counter + 1
    26. Else
    27. System.IO.File.Copy(source, Destination, True)
    28. counter = counter + 1
    29. TextBox1.AppendText(CStr("\") + lastline & Environment.NewLine)
    30. ToolStripStatusLabel2.Text = counter
    31. End If
    32. Catch
    33. 'MsgBox("Datei " & source & " konnte nicht kopiert werden!")
    34. If File.Exists(source) Then
    35. TextBox2.AppendText("Konnte nicht kopiert werden: " & CStr("\") + lastline & Environment.NewLine)
    36. err_counter = err_counter + 1
    37. Else
    38. TextBox2.AppendText("Nicht gefunden: " & CStr("\") + lastline & Environment.NewLine)
    39. err_counter = err_counter + 1
    40. End If
    41. ToolStripStatusLabel4.Text = err_counter
    42. ToolStripStatusLabel6.Text = info_counter
    43. End Try
    44. End If
    45. End If
    46. Next
    47. ToolStripStatusLabel1.Visible = True
    48. ToolStripStatusLabel2.Visible = True
    49. ToolStripStatusLabel3.Visible = True
    50. ToolStripStatusLabel4.Visible = True
    51. ToolStripStatusLabel5.Visible = True
    52. ToolStripStatusLabel6.Visible = True
    53. Button3.Enabled = True
    54. End Sub
    Nein! Doch! OHH!
    Drücke ich mich unklar aus? Ich sagte:

    ErfinderDesRades schrieb:

    schreib die Methode am besten um in eine Function, der du die nötigen Argumente übergibst, und die dann einen Antwort-String zurückgibt.
    Wo in deinem Kladeradatsch ist nun die von mir vorgeschlagene/angefragte Function?

    Naja - vlt wirklich nicht tausendprozentig präzise formuliert - also nochmal:
    Schreibe eine zusätzliche Function, der du die nötigen Argumente übergibst, die dann den Kopier-Vorgang durchführt (bzw es versucht), und anschließend einen Antwort-String zurückgibt.
    Schreibe nicht alles in deine Button_Click-Sub, sondern schreibe diese Methode, und ruf sie von deiner Button_Click-Sub aus auf.
    (Diesen Aufruf kann man dann mit Leichtigkeit nach Async transferieren - das würde ich dir gerne zeigen.)

    Nun klarer?


    (Übrigens wie man sieht, ist ja doch eine Schleife anhängig, womit Counterbugs Ansatz wieder denkbar ist.
    Nur soviel: Mein Ansatz ist ein anderer.)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    @ErfinderDesRades ich bin mir nicht sicher, aber ist es das was du meinst?

    VB.NET-Quellcode

    1. Private Function func_copy(ByVal bdt As String) As String
    2. Button3.Enabled = False
    3. Dim counter As Integer = 0
    4. Dim err_counter As Integer = 0
    5. Dim info_counter As Integer = 0
    6. Dim sFile As String = bdt
    7. System.IO.File.Copy(OpenFileDialog1.FileName, FolderBrowserDialog1.SelectedPath + "\" + sFile, True)
    8. If File.Exists(OpenFileDialog1.FileName) Then
    9. TextBox1.AppendText("BDT Datei in Zielverzeichnis kopiert:" & sFile & Environment.NewLine)
    10. End If
    11. For Each line In IO.File.ReadLines(OpenFileDialog1.FileName)
    12. If line.Contains(My.Settings.such_str) Then
    13. Dim line2 As String = CStr(line)
    14. Dim newline As String = line2.Remove(0, line2.IndexOf(My.Settings.such_str))
    15. Dim lastline = newline
    16. Dim source = FolderBrowserDialog2.SelectedPath + CStr("\") + lastline
    17. Dim copyline = FolderBrowserDialog2.SelectedPath + CStr("\") + lastline
    18. Dim Destination As String = FolderBrowserDialog1.SelectedPath + CStr("\") + lastline
    19. Dim sPath As String = FolderBrowserDialog1.SelectedPath + CStr("\") + IO.Path.GetDirectoryName(lastline)
    20. If Directory.Exists(FolderBrowserDialog2.SelectedPath) Then
    21. Directory.CreateDirectory(sPath)
    22. Try
    23. If File.Exists(Destination) Then
    24. TextBox2.AppendText("Datei bereits vorhanden" & Environment.NewLine)
    25. info_counter = info_counter + 1
    26. Else
    27. System.IO.File.Copy(source, Destination, True)
    28. counter = counter + 1
    29. TextBox1.AppendText(CStr("\") + lastline & Environment.NewLine)
    30. ToolStripStatusLabel2.Text = counter
    31. End If
    32. Catch
    33. 'MsgBox("Datei " & source & " konnte nicht kopiert werden!")
    34. If File.Exists(source) Then
    35. TextBox2.AppendText("Konnte nicht kopiert werden: " & CStr("\") + lastline & Environment.NewLine)
    36. err_counter = err_counter + 1
    37. Else
    38. TextBox2.AppendText("Nicht gefunden: " & CStr("\") + lastline & Environment.NewLine)
    39. err_counter = err_counter + 1
    40. End If
    41. ToolStripStatusLabel4.Text = err_counter
    42. ToolStripStatusLabel6.Text = info_counter
    43. End Try
    44. End If
    45. End If
    46. Next
    47. ToolStripStatusLabel1.Visible = True
    48. ToolStripStatusLabel2.Visible = True
    49. ToolStripStatusLabel3.Visible = True
    50. ToolStripStatusLabel4.Visible = True
    51. ToolStripStatusLabel5.Visible = True
    52. ToolStripStatusLabel6.Visible = True
    53. Button3.Enabled = True
    54. End Function


    Danke und Grüße Stefan
    Nein! Doch! OHH!
    ich sehe nicht, dass die Function irgendetwas zurückgäbe.
    Ein rückgabewert ist zwar deklariert, aber wo ist die Return-Anweisung?

    Aber die Funktion sollte auch viel kleiner sein.
    Das Problem ist, du kannst aus einem Neben-Thread keine Steuerelemente ansprechen - nicht die Textbox, nicht das Label, nicht das Toolstrip-Item.
    Das muss alles ausserhalb der Function passieren.
    Mach die function klein, und sie soll sich einzig drauf konzentrieren, eine einzige Datei zu kopieren versuchen, und nichts sonst.
    Und entsprechend ob das geklappt hat den Antwort-Text zurückgeben.
    Den restlichen Kladeradatsch lass mw. in Button_Click, und von da aus, in der Schleife rufst du deine Kopier-Function auf.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Sorry, @ErfinderDesRades ich kann dir nicht mehr folgen...
    Ich muss ja die BDT Datei einlesen... Darin stehen die Pfade die ich mittels If line.Contains(My.Settings.such_str) suche...
    wie soll ich das "kleiner" machen? Tut mir leid, ich bin es von PHP gewohnt, eine Anweisung komplett auszulagern... ist für mich immernoch alles Neuland.
    Nein! Doch! OHH!
    ich muss gestehen, ich verwende in PHP Klassen, keine Funktionen ;)
    Die Klassen beinhalten meist alles... Selten das da noch viel drum rum gemacht wird.

    wenn ich dein Beispiel korrekt deute, sollte es hinterher ungefähr so aussehen oder?

    VB.NET-Quellcode

    1. Private Function func_copy(source as String, destination As String) As string
    2. If Directory.Exists(FolderBrowserDialog2.SelectedPath) Then
    3. Directory.CreateDirectory(sPath)
    4. Try
    5. If File.Exists(Destination) Then
    6. TextBox2.AppendText("Datei bereits vorhanden" & Environment.NewLine)
    7. Else
    8. System.IO.File.Copy(source, Destination, True)
    9. TextBox1.AppendText(CStr("\") + lastline & Environment.NewLine)
    10. ToolStripStatusLabel2.Text = counter
    11. End If
    12. Catch
    13. 'MsgBox("Datei " & source & " konnte nicht kopiert werden!")
    14. If File.Exists(source) Then
    15. TextBox2.AppendText("Konnte nicht kopiert werden: " & CStr("\") + lastline & Environment.NewLine)
    16. Else
    17. TextBox2.AppendText("Nicht gefunden: " & CStr("\") + lastline & Environment.NewLine)
    18. End If
    19. End Try
    20. End If
    21. End function


    oder ist da immernoch was zuviel?
    Nein! Doch! OHH!

    ErfinderDesRades schrieb:

    Das Problem ist, du kannst aus einem Neben-Thread keine Steuerelemente ansprechen - nicht die Textbox, nicht das Label, nicht das Toolstrip-Item.
    Das muss alles ausserhalb der Function passieren.

    Textbox und ToolStripStatusLabel kannst du aus dem geplanten NebenThread nicht ansprechen - statt in die Textbox reinzuschreiben, gib den Text als Rückgabewert zurück.

    Und dann poste auch, wie diese Methode aufgerufen wird, dass man den Aufruf ummodeln kann.

    Edit: Und der FolderBrowser hat in der Methode auch nix verloren, und CreateDirectory ebensowenig.
    Die Function soll sich auf ihren Job konzentrieren, sonst garnichts.
    Hey,

    lies das:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim a As Integer = 2
    3. Dim b As Integer = Verdoppeln(a)
    4. MessageBox.Show(b)
    5. End Sub
    6. Private Function Verdoppeln(ByVal Zahl As Integer) As Integer
    7. Dim Doppel As Integer = 2 * Zahl
    8. Return Doppel
    9. End Function

    gehe in dich und versuche zu verstehen :D Tja und sag mir was da rauskommt...
    Wer fragt, ist ein Narr für eine Minute. Wer nicht fragt, ist ein Narr sein Leben lang.