Prozess ausführen ohne Form zu blockieren

  • VB.NET
  • .NET (FX) 4.0

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von razzzer530i.

    Prozess ausführen ohne Form zu blockieren

    Moin,

    kurze Frage:

    Ich habe eine Form mit verschiedenen Objekten. Drücke ich jetzt Button1, dann wird etwas gemacht. Z.B. eine riesige Textdatei geschrieben. Während das passiert, blockiert die Form, d.h., wenn ich z.B. den Fortschritt live anzeigen möchte, dann funktioniert das erst, nachdem der Prozess beendet ist.

    Wie kann ich auf einer Form weiterarbeiten, auch gerade gearbeitet wird?

    Danke für jede Hilfe!
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Hier gibt es ein gutes Tutorial von @ErfinderDesRades wo er Async/Await/Task erklärt. Da kannst du auch ein Bespiel nebenbei mit programmieren und sehen wie sich diese Methoden verhalten.

    vb-paradise.de/index.php/Thread/108880-Async-Await-und-Task/

    Mit freundlichen Grüßen
    Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    Verstehe da leider nicht so wirklich, wie ich damit einen Prozess bzw eine einfache Funktion die etwas tut, swo ausführen kann, dass sie den Rest nicht stoppt.
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Hier ein kurzes Beispiel, leider in C#

    C#-Quellcode

    1. private async void button1_Click(object sender, EventArgs e)
    2. {
    3. //Freeeeeeeeeze
    4. DoHeavyStuff();
    5. //No Freeze
    6. await DoMoreHeavyStuffAsync();
    7. }
    8. public void DoHeavyStuff()
    9. {
    10. Thread.Sleep(5000);
    11. MessageBox.Show("finished");
    12. }
    13. public async Task DoMoreHeavyStuffAsync()
    14. {
    15. await DoHeavyStuffAsync();
    16. await DoHeavyStuffAsync();
    17. MessageBox.Show("finished");
    18. }
    19. public Task DoHeavyStuffAsync()
    20. {
    21. return Task.Run(() =>
    22. {
    23. Thread.Sleep(5000);
    24. });
    25. }

    Der Telerik CodeConverter spuckt dafür folgendes aus:

    VB.NET-Quellcode

    1. Private Sub button1_Click(sender As Object, e As EventArgs)
    2. 'Freeeeeeeeeze
    3. DoHeavyStuff()
    4. 'No Freeze
    5. Await DoMoreHeavyStuffAsync()
    6. End Sub
    7. Public Sub DoHeavyStuff()
    8. Thread.Sleep(5000)
    9. MessageBox.Show("finished")
    10. End Sub
    11. Public Function DoMoreHeavyStuffAsync() As Task
    12. Await DoHeavyStuffAsync()
    13. Await DoHeavyStuffAsync()
    14. MessageBox.Show("finished")
    15. End Function
    16. Public Function DoHeavyStuffAsync() As Task
    17. Return Task.Run(Function()
    18. Thread.Sleep(5000)
    19. End Function

    Mit dem Thread von @ErfinderDesRades sollte es jedoch möglich sein, das korrekt umzuwandeln.
    An sich wirklich klasse, glaube dass das auch genau das ist was ich meine.

    Aber ich kriege es null hin.

    Ich habe eine public sub x die in einem modul steht

    jetzt drücke ich auf meiner form auf button1 und möchte, dass die sub x ausgeführt wird. Während diese im Hintergrund ausgeführt wird soll sich auf der Form was verändern.

    VB.NET-Quellcode

    1. Private Sub button1_Click(sender As Object, e As EventArgs)
    2. await x()
    3. timer1.start ' im timer ändert sich eine Anzeige auf der Form
    4. End Sub


    Weiter komme ich absolut nicht. Wieso auch immer.

    Möchte nur, dass meine Sub aus Modul1 ausgeführt wird, auf der Form jedoch der Timer noch meinetwegen ein Label alle 500ms ändert.

    Verstehe die Funktionsweise da nicht.

    Sorry :X

    Vielleicht hilft mir eine einfache Erklärung
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Zunächst was sehr wichtiges was Async/Await angeht:
    EventHandler sind die einzigen Subs, die man mit Async dekorieren sollte. Alles andere was man Async ausführen möchte, sollte eine Function xyz() As Task sein.

    razzzer530i schrieb:

    Ich habe eine public sub x die in einem modul steht

    Man kann Subs nicht awaiten, da sie einem nichts zurückgeben, was man awaiten könnte.
    Okay, also ich kann aus der Sub auch eine Funion machen.
    In meiner Sub analysiere ich ca 2000 Dateien. Davon hole ich mir pro Datei ca 16 Metadaten.
    Diese adde ich dann zu einer Listbox.
    Außerdem schreibe ich die Metadaten noch in eine .txt Datei

    Solange das in meiner (Noch) sub passiert, funktioniert nichts anderes. Die Form gibt keine Rückmeldung.

    Das ist das Problem was ich habe. Weiß nicht, wie ich das so verwenden könnte, dass es ohne Probleme klappt.

    Kleinen Arschtritt für mich ? :x :D
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~
    Also ich benutze eigentlich 4.5 , muss aber auf 4.0 runtergehen, wenn es an allen Rechnern hier funktionieren soll.
    VS 2015 verwende ich.

    Habe mehrere Checkboxen, die entscheiden, welche Daten gebraucht werden. Vielleicht kann man das ganze auch noch extrem abkürzen. Wüsste allerdings nicht wie...

    Ich poste hier einfahc mal die Funktion bzw. mein sub.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public PDFCD As String
    2. Public PDFMD As String
    3. Public Sub PDFsettingsF()
    4. Dim a As String = Form1.FolderBrowserDialog1.SelectedPath
    5. Dim di As New System.IO.DirectoryInfo(a)
    6. Dim fs As New FileStream(Form1.datei, FileMode.Create)
    7. Dim sw As New StreamWriter(fs)
    8. Dim toppingsx As String = ""
    9. 'Allgemein
    10. If Form1.Allgname.Checked = True Then
    11. toppingsx &= Form1.Allgname.Text & vbTab
    12. End If
    13. If Form1.AllgTyp.Checked = True Then 'Typ
    14. toppingsx &= Form1.AllgTyp.Text & vbTab
    15. End If
    16. If Form1.AllgGroesse.Checked = True Then 'Name
    17. toppingsx &= Form1.AllgGroesse.Text & vbTab
    18. End If
    19. If Form1.AllgOrt.Checked = True Then 'Pfad
    20. toppingsx &= Form1.AllgOrt.Text & vbTab
    21. End If
    22. If Form1.AllgErstellt.Checked = True Then 'Erstellungsdatum
    23. toppingsx &= Form1.AllgErstellt.Text & vbTab
    24. End If
    25. If Form1.Allggeaendert.Checked = True Then 'Änderungsdatum
    26. toppingsx &= Form1.Allggeaendert.Text & vbTab
    27. End If
    28. If Form1.Allglz.Checked = True Then 'Letzter Zugriff
    29. toppingsx &= Form1.Allglz.Text & vbTab
    30. End If
    31. 'PDF
    32. If Form1.PDFAuthor.Checked = True Then
    33. toppingsx &= Form1.PDFAuthor.Text & vbTab
    34. End If
    35. If Form1.PDFTitel.Checked = True Then
    36. toppingsx &= Form1.PDFTitel.Text & vbTab
    37. End If
    38. If Form1.PDFCreationDate.Checked = True Then
    39. toppingsx &= Form1.PDFCreationDate.Text & vbTab
    40. End If
    41. If Form1.PDFBearbeitugnsd.Checked = True Then
    42. toppingsx &= Form1.PDFBearbeitugnsd.Text & vbTab
    43. End If
    44. If Form1.PDFErstlprg.Checked = True Then
    45. toppingsx &= Form1.PDFErstlprg.Text & vbTab
    46. End If
    47. If toppingsx <> "" Then
    48. sw.WriteLine(toppingsx)
    49. Form1.ListBox1.Items.Add(toppingsx)
    50. End If
    51. For Each fi As System.IO.FileInfo In di.GetFiles("*.pdf", System.IO.SearchOption.AllDirectories)
    52. Dim pdfr As New iTextSharp.text.pdf.PdfReader(fi.FullName)
    53. Dim ht As Hashtable = New Hashtable(pdfr.Info)
    54. Try
    55. Dim CD As String = ht("CreationDate") 'PDF Erstelldatum
    56. CD = CD.Remove(0, 2)
    57. Dim Year As String = CD.Substring(0, 4)
    58. Dim month As String = CD.Substring(4, 2)
    59. Dim day As String = CD.Substring(6, 2)
    60. Dim time As String = CD.Substring(8, 6)
    61. CD = day & "." & month & "." & Year
    62. PDFCD = CD
    63. Dim MD As String = ht("ModDate") 'PDF Bearbeitungsdatum
    64. MD = MD.Remove(0, 2)
    65. Dim mYear As String = MD.Substring(0, 4)
    66. Dim mmonth As String = MD.Substring(4, 2)
    67. Dim mday As String = MD.Substring(6, 2)
    68. Dim mtime As String = MD.Substring(8, 6)
    69. MD = mday & "." & mmonth & "." & mYear
    70. PDFMD = MD
    71. Catch ex As Exception
    72. Dim CD As String = ht("CreationDate")
    73. Dim MD As String = ht("ModDate")
    74. PDFMD = MD
    75. End Try
    76. Dim AT As String = ht("Author")
    77. Dim TI As String = ht("Title")
    78. Dim CS As String = ht("Creator") 'Erzeugungsprogramm
    79. Dim FN As String = fi.Name
    80. FN = FN.Replace(".pdf", "")
    81. Dim DT As String = fi.Extension
    82. DT = DT.Replace(DT, "PDF")
    83. Dim ED As String = fi.CreationTime
    84. Dim BD As String = fi.LastWriteTime
    85. Dim LA As String = fi.LastAccessTime
    86. Dim Si As String = fi.Length & " Byte"
    87. Dim FNN As String = fi.FullName
    88. Dim toppings As String = ""
    89. 'Allgemein
    90. If Form1.Allgname.Checked = True Then 'Größe
    91. toppings &= FN & vbTab
    92. End If
    93. If Form1.AllgTyp.Checked = True Then 'Typ
    94. toppings &= DT & vbTab
    95. End If
    96. If Form1.AllgGroesse.Checked = True Then 'Name
    97. toppings &= Si & vbTab
    98. End If
    99. If Form1.AllgOrt.Checked = True Then 'Pfad
    100. Try
    101. toppings &= FNN & vbTab
    102. Catch
    103. toppings &= Form1.Batchpath & vbTab
    104. End Try
    105. End If
    106. If Form1.AllgErstellt.Checked = True Then 'Erstellungsdatum
    107. toppings &= ED & vbTab
    108. End If
    109. If Form1.Allggeaendert.Checked = True Then 'Änderungsdatum
    110. toppings &= BD & vbTab
    111. End If
    112. If Form1.Allglz.Checked = True Then 'Letzter Zugriff
    113. toppings &= LA & vbTab
    114. End If
    115. 'PDF
    116. If Form1.PDFAuthor.Checked = True Then
    117. toppings &= AT & vbTab
    118. End If
    119. If Form1.PDFTitel.Checked = True Then
    120. toppings &= TI & vbTab
    121. End If
    122. If Form1.PDFCreationDate.Checked = True Then
    123. toppings &= PDFCD & vbTab
    124. End If
    125. If Form1.PDFBearbeitugnsd.Checked = True Then
    126. toppings &= PDFMD & vbTab
    127. End If
    128. If Form1.PDFErstlprg.Checked = True Then
    129. toppings &= CS & vbTab
    130. End If
    131. If toppings <> "" Then
    132. sw.WriteLine(toppings)
    133. Form1.ListBox1.Items.Add(toppings)
    134. End If
    135. Next
    136. sw.Close()
    137. End Sub


    Das hier ist ein kleiner Teil, eine Sub, die mir mehere Metadaten direkt in eine Textdatei und Listbox schreibt.

    Diese würde ich gerne so ausgliedern, dass sich die Listbox bei jedem Eintrag aktualisiert.(Live sehen was passiert). GGf möchte ich noch ein "Wird verarbeitet" oder ähnliches aufblinken lassen.

    Mag sein dass es etwas kaotisch ist, aber bin hier gerade zum ersten Mal an solchen Sachen dran.

    //Edit

    Problem durch das oben angegebene Tutorial letzendlich doch gelöst!
    ~Wir leben zwar alle unter dem gleichen Himmel, aber es haben nicht alle den gleichen Horizont~

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