loop / Liste / auf Task warten / Portionieren?

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    loop / Liste / auf Task warten / Portionieren?

    Hallo!

    Ich habe eine Liste mit sehr vielen Einträgen! Wenn ich diese Liste nun per Schleife durchlaufe bekomme ich ein OutOfMemory-Error!

    Nun wollte ich die große Liste in mehrere kleinere Listen aufteilen, was ich auch schon habe!

    Was nun noch fehlt ist es dem Programm zu sagen wann er die nächste Liste anfangen darf, weil er sonst in der Schleife trotzdem alle Einträge inn Speicher laden will!

    Ich dachte da an Tasks und an Task.wait().

    Oder wie kann ich in einer Schleife warten bis eine Liste abgearbeitet ist?!?
    Oder wie kann ich die große Liste, in Schritten von 4192 Einträgen, abarbeiten?!?
    Was ist das für eine Liste? Was macht du in der Schleife? Wann lädst du die Daten und wie? Irgendwie passen deine Aussagen nicht ganz richtig zusammen. Etwas mehr Informationen wäre hilfreich. Eine Liste ist immer im Speicher also wenn du beim durchlaufen eine OutOfMemory bekommst klingt das eher danach, dass du in der Schleife was falsch machst. Arbeitest du nicht schon mit Threads,Tasks oder Parallel? Du Fragst, wie du dem Programm sagen kannst, dass er auf die Abarbeitung einer Liste warten soll, aber eine for oder foreach läuft von alleine nicht parallel. Da wird Eintrag für Eintrag einzeln und nacheinander abgearbeitet.

    Morrison schrieb:

    gelöst
    Was hat dieser Code mit Deinem Problem zu tun?
    Wenn Du eine große Anzahl in 4096er Schritten abarbeiten willst, musst Du zwei Schleifen machen, z.b.:

    VB.NET-Quellcode

    1. For i = 0 To GROßE_ZAHL Step 4096
    2. For j = 0 To 4095
    3. If feddich Then RAUS
    4. Next
    5. Next
    Das mit dem RAUS ist wichtig, wenn die GROßE_ZAHL nicht durch 4096 teilbar ist, lässt sich vielfältig lösen.
    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!
    Oh ja @RodFromGermany

    Auf den ersten Blick nicht einmal gleich ersichtlich.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Module Module1
    4. Public Sub Main()
    5. Bsp1()
    6. Bsp2()
    7. End Sub
    8. Private Sub Bsp1()
    9. 'Eine ListOfT erstellen und die dann auf die 4096 splitten
    10. Dim n1 As Int32 = 4096
    11. Dim n2 As Int32 = n1 * 50 - 100 'Irgend eine Grösse
    12. Dim l As New List(Of Int64)(n2)
    13. createArr(l, n2)
    14. Dim n As Int32 = (n2 \ n1) + 1
    15. Dim lst As New List(Of List(Of Int64))(n)
    16. spliArr(lst, l, n, n1)
    17. For i As Integer = 0 To lst.Count - 1
    18. For j As Integer = 0 To lst(i).Count - 1
    19. Stop 'mach was
    20. Next
    21. Next
    22. End Sub
    23. Private Sub Bsp2()
    24. 'gleich von Anfang an eine ListOfT die die 4096 beachtet
    25. Dim n1 As Int32 = 4096
    26. Dim n2 As Int32 = n1 * 50 - 100 'Irgend eine Grösse
    27. Dim n As Int32 = 5' (n2 \ n1) + 1
    28. Dim lst As New List(Of List(Of Int64))(n)
    29. createArr(lst, n, n1, n2)
    30. For i As Integer = 0 To lst.Count - 1
    31. For j As Integer = 0 To lst(i).Count - 1
    32. Stop 'mach was
    33. Next
    34. Next
    35. End Sub
    36. Private Sub createArr(ByRef lst As List(Of Int64), ByVal n As Int32)
    37. For i As Integer = 0 To n
    38. lst.Add(i)
    39. Next
    40. End Sub
    41. Private Sub spliArr(ByRef lst1 As List(Of List(Of Int64)), ByVal lst2 As List(Of Int64), ByVal n As Int32, ByVal n1 As Int32)
    42. Dim n3 As Int32 = ((lst2.Count - (lst2.Count Mod n1)) \ (n - 1))
    43. Dim l As List(Of Int64)
    44. For i As Integer = 0 To n - 1
    45. l = New List(Of Int64)(n3)
    46. For j As Int32 = 0 To n3 - 1
    47. l.Add(lst2(i * n3 + j))
    48. If (i * n3 + j) >= lst2.Count - 1 Then
    49. Exit For
    50. End If
    51. Next
    52. lst1.Add(l)
    53. Next
    54. End Sub
    55. Private Sub createArr(ByRef lst As List(Of List(Of Int64)), ByVal n As Int32, ByVal n1 As Int32, ByVal n2 As Int32)
    56. Dim n3 As Int32 = ((n2 - (n2 Mod n1)) \ (n - 1))
    57. Dim l As List(Of Int64)
    58. For i As Integer = 0 To n - 1
    59. l = New List(Of Int64)(n3)
    60. For j As Int32 = 0 To n3 - 1
    61. l.Add(i * n3 + j)
    62. If (i * n3 + j) >= n2 Then
    63. Exit For
    64. End If
    65. Next
    66. lst.Add(l)
    67. Next
    68. End Sub
    69. End Module


    Korrektur: Kurz umgestellt.

    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „exc-jdbi“ ()

    Wenn sich der TE ne OutOfMemoryExeption einfängt hört sich das eher so an, als wenn an der Schleife was kaputt ist oder aber, dass die berechnungen dort so lange dauern das Windows "abbricht".

    Morrison schrieb:

    OK, habs jetzt so gelöst:
    Hm, ja kann man so machen. Aber das ist ne "Pfuscher-Lösung" die du so niemandem zeigen darfst ;)

    Schau dir mal das Thema Await/Async an. Das wäre ne saubere Lösung
    "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
    ich fühl da immer etwas eigentümlich, wenn jemand ein Thema "anschauen" soll.

    Wie konkret soll das vor sich gehen?
    Soll er die Begriffe googeln, und hoffen, zufällig ein für ihn geeignetes Tutorial zu finden?
    Ich hab Async/Await grad nicht gegoogelt, aber ich gehe mal davon aus, da fährt auch jede Menge Blödsinn zu rum im INet. Selbst MSDN hats echt drauf, schwachsinnige Codebeispiele zu bringen - MSDN-Codebeispiele sollte man unbesehen nicht unbedingt empfehlen.
    (Da fällt mir grad ein: Ich hab ja selbst Tuts dazu gemacht, und das bedeutet, dass ich (damals) auch nichts brauchbares fund)

    Oder setzst du voraus, dasser ein gutes, aktuelles .Net - Lehrbuch vorhält, worinnen er ein entsprechendes Kapitel findet?

    Grade Threading/Nebenläufigkeit - dafür muss man ühaupt erstmal verstehen, was damit möglich/sinnvoll ist und was nicht.
    Etwa eine Schleife im Nebenthread, die ständig das Gui aktualisiert, ist möglich, aber nicht sinnvoll. Trotzdem versucht ungefähr jeder Threading-Anfänger, genau so eine Schleife umzusetzen.

    Wie dem auch sei - wenn man denn Nebenläufigkeit so einigermassen verstanden hat, gehts immer noch daran, erstmal Code-Architektur umzubauen, um den Gui-zugreifenden Code vom nebenläufigkeits-tauglichen Code zu trennen.

    Und da stößt man meist aufs nächste Problem: Sind die Begriffe Function, Argument, Rückgabewert, Aufrufer, Datentyp so weit geläufig, dass der TE überhaupt auch nur eine Function (mw. leer) anlegen könnte, worinnen die Nebenläufigkeit abgearbeitet werden könnte?
    Das ist bei sehr sehr vielen garnet gegeben.

    Soo - und dann! - kann es helfen "Async/Await angucken" - weil dann ists nur noch ein Klacks.
    Dann brauch man eiglich nichtmal mehr gross angucken, sondern das kann man auch servieren, weil sind ja nur 2 Einfügungen beim Aufrufer.

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