"For Each" Fehler

  • VB.NET
  • .NET 4.5

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

    "For Each" Fehler

    Hallo habe seit kurzem einen kuriosen Fehler, den ich mir nicht erklären kann. Es wird nicht Parallel darauf zugegriffen.

    Hier mal der Code.

    VB.NET-Quellcode

    1. Dim workinglist As List(Of Integer) = CalculationIDList 'Funktion die eine Liste mit Integern wiedergibt
    2. For Each CalculationID As Integer In workinglist
    3. 'Mach etwas
    4. Next


    Jetzt sagt mir VSStudio im Debug Modus ab und anmal bei der For Each Schleife "Index ausserhalb des Arraybereichs" wie ist das möglich?
    Dazu müsste man halt auch wissen, was sich hinter 'Mach etwas verbirgt.
    veränderst du eventuell innerhalb der ForEach die List(Of Integer)?
    Entfernst du, oder fügst du neue Elemente hinzu? Das geht nicht, solange du dich in der ForEach befindest
    SIMDoku (Simple Dokumentenverwaltung)
    Mein Lernprojekt um die verschiedensten Facetten der .NET Entwicklung zu erkunden.
    GitHub

    VB Paradise Dark Theme
    Inoffizieller VB-Paradise Discord.
    Nein Natürlich verändere ich die workinglist nicht :-).

    Ich Arbeite nur mit den Integer Zahlen, auch ist die Liste kpl. gefüllt, also kein 'Nothing' etc..
    Habe das mit einer Try Catch anweisung abgefangen, finde es aber keine schöne lösung.
    Poste bitte mal den ganzen code. Weil das was du gepostet hast ist an sich ok.
    "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
    @mrMo Bitte schön :) Der Fehler tritt in der Funktion TradeSettingsTable2 auf. Aufgerufen wird das ganze mit "GetTradeSettingString"

    VB.NET-Quellcode

    1. Public Function GetTradeSettingString(ByVal Instrument As String, ByVal TradeDirection As String, ByVal SelectedRow As DataRow, Optional ByVal Reload As Boolean = False, Optional ByVal Setting As Boolean = False) As String
    2. If Reload Then
    3. GetDataTable(Tradesetting_Table)
    4. End If
    5. Dim ReturningString As String = "NoInformation"
    6. Select Case Tradesetting_Table
    7. Case 0
    8. ReturningString = TradeSettingsTable1(Instrument, TradeDirection, SelectedRow)
    9. Case 1
    10. ReturningString = TradeSettingsTable2(Instrument, TradeDirection, SelectedRow, Setting)
    11. End Select
    12. Return ReturningString
    13. End Function
    14. Public Function TradeSettingsTable2(ByVal Instrument As String, ByVal TradeDirection As String, ByVal SelectedRow As DataRow, Optional ByVal Setting As Boolean = False) As String
    15. Dim ReturningString As String = "NoInformation"
    16. Dim FoundRow() As DataRow = TradeSettingsTable.Select("Instrument = '" & Instrument & "' AND Active = 'True' AND TradeDirection = '" & TradeDirection & "' AND SubCalculationID = '0'")
    17. Dim CalculationIDList As List(Of Integer) = GetFirstTradeInformation(FoundRow, SelectedRow)
    18. If Not CalculationIDList Is Nothing Then
    19. Dim workinglist As List(Of Integer) = CalculationIDList
    20. Try
    21. For Each CalculationID As Integer In workinglist
    22. If Setting = False Then
    23. Dim SecondFoundRow() As DataRow = TradeSettingsTable.Select("Instrument = '" & Instrument & "' AND Active = 'True' AND TradeDirection = '" & TradeDirection & "' AND SubCalculationID = '1' AND CalculationID = '" & CalculationID & "'")
    24. ReturningString = GetTradeInformation(SecondFoundRow, SelectedRow)
    25. Else
    26. ReturningString = "Trade"
    27. End If
    28. Next
    29. Catch ex As Exception
    30. Debug.Print("Index Ausserhalb des Arraybereichs: " & ReturningString)
    31. End Try
    32. End If
    33. Return ReturningString
    34. End Function
    35. Public Function GetFirstTradeInformation(ByVal FoundRows() As DataRow, ByVal SelectedRow As DataRow) As List(Of Integer)
    36. Dim ReturningIntegerList As List(Of Integer)
    37. Dim po As New ParallelOptions()
    38. Parallel.ForEach(FoundRows, po, Sub(SettingsRow)
    39. If IsDBNull(SettingsRow("Volume_1")) = False And IsDBNull(SettingsRow("Volume_2")) = False Then
    40. Dim Boolean_1 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_1")), CInt(SettingsRow("Symbol_1")), CStr(SettingsRow("ColumName")), SelectedRow)
    41. Dim Boolean_2 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_2")), CInt(SettingsRow("Symbol_2")), CStr(SettingsRow("ColumName")), SelectedRow)
    42. If Boolean_1 And Boolean_2 Then
    43. ReturningIntegerList = AddNewInteger(CInt(SettingsRow("CalculationID")), ReturningIntegerList)
    44. po.CancellationToken.ThrowIfCancellationRequested()
    45. End If
    46. ElseIf IsDBNull(SettingsRow("Volume_1")) = False Then
    47. Dim Boolean_1 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_1")), CInt(SettingsRow("Symbol_1")), CStr(SettingsRow("ColumName")), SelectedRow)
    48. If Boolean_1 Then
    49. ReturningIntegerList = AddNewInteger(CInt(SettingsRow("CalculationID")), ReturningIntegerList)
    50. po.CancellationToken.ThrowIfCancellationRequested()
    51. End If
    52. ElseIf IsDBNull(SettingsRow("Volume_2")) = False Then
    53. Dim Boolean_1 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_2")), CInt(SettingsRow("Symbol_2")), CStr(SettingsRow("ColumName")), SelectedRow)
    54. If Boolean_1 Then
    55. ReturningIntegerList = AddNewInteger(CInt(SettingsRow("CalculationID")), ReturningIntegerList)
    56. po.CancellationToken.ThrowIfCancellationRequested()
    57. End If
    58. End If
    59. End Sub)
    60. Return ReturningIntegerList
    61. End Function
    @mrMo Geschätzt diese:

    Rattenfänger schrieb:

    VB.NET-Quellcode

    1. ReturningString = GetTradeInformation(SecondFoundRow, SelectedRow)
    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!
    @ErfinderDesRades Habich glatt ignoriert. :D
    Mein Tipp bleibt trotzdem bestehen.
    @Rattenfänger Wie wärs mit Haltepunkt und Debuggen?
    Debuggen, Fehler finden und beseitigen
    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!
    In zeile 48. Genau bei next.

    @Fakiz das könnte sein. Habe ich ja noch gar nicht dran gedacht ;-)! Werde dort gleich mal Debuggen.

    @RodFromGermany das debuggen ist gar nicht so einfach, bis der Fehler auftritt, muss das Programm 3std. durchlaufen und dann ist noch nicht mal sicher ob der Fehler auftritt.

    Rattenfänger schrieb:

    bis der Fehler auftritt, muss das Programm 3std. durchlaufen
    Ist doch einfach: Warte, bis es knallt.
    Allerdings solltest Du das Try / Catch rausnehmen, dann knallt es genau da, wo der Fehler auftaucht.
    Wenn mit Try / Catch, setze in den Catch-Zweig den Haltepunkt, um den StackTrace auslesen zu können.
    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!
    Jetzt haben wir zwar viel Code. Aber nicht die Sub GetTradeInformation (es gibt den Code für GetFirstTradeInformation, aber nicht für GetTradeInformation), die offensichtlich Probleme macht. Spekulatiusbacken ist angesagt :(
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    @VaporiZed Bitte schön, einmal die GeTradeInformation, ist eigentlich das selbe wie GetFirstTradeInformation :-). Gibt hier aber einen String zurück.
    @RodFromGermany das ist genau da wo ich gesagt habe, zeile 48 next. So unglaublich es ist.

    VB.NET-Quellcode

    1. Public Function GetTradeInformation(ByVal FoundRows() As DataRow, ByVal SelectedRow As DataRow) As String
    2. Dim ReturningString As String = "NoInformation"
    3. Dim po As New ParallelOptions()
    4. System.Threading.Tasks.Parallel.ForEach(FoundRows, po, Sub(SettingsRow)
    5. If IsDBNull(SettingsRow("Volume_1")) = False And IsDBNull(SettingsRow("Volume_2")) = False Then
    6. Dim Boolean_1 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_1")), CInt(SettingsRow("Symbol_1")), CStr(SettingsRow("ColumName")), SelectedRow)
    7. Dim Boolean_2 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_2")), CInt(SettingsRow("Symbol_2")), CStr(SettingsRow("ColumName")), SelectedRow)
    8. If Boolean_1 And Boolean_2 Then
    9. ReturningString = CStr(SettingsRow("ReturningValue"))
    10. po.CancellationToken.ThrowIfCancellationRequested()
    11. End If
    12. ElseIf IsDBNull(SettingsRow("Volume_1")) = False Then
    13. Dim Boolean_1 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_1")), CInt(SettingsRow("Symbol_1")), CStr(SettingsRow("ColumName")), SelectedRow)
    14. If Boolean_1 Then
    15. ReturningString = CStr(SettingsRow("ReturningValue"))
    16. po.CancellationToken.ThrowIfCancellationRequested()
    17. End If
    18. ElseIf IsDBNull(SettingsRow("Volume_2")) = False Then
    19. Dim Boolean_1 As Boolean = CheckVolume(CDbl(SettingsRow("Volume_2")), CInt(SettingsRow("Symbol_2")), CStr(SettingsRow("ColumName")), SelectedRow)
    20. If Boolean_1 Then
    21. ReturningString = CStr(SettingsRow("ReturningValue"))
    22. po.CancellationToken.ThrowIfCancellationRequested()
    23. End If
    24. End If
    25. End Sub)
    26. Return ReturningString
    27. End Function
    Was ich nicht verstehe: Was hat eine IndexOutOfRange-Exception mit ner ForEach-Loop zu tun? Wenn die Auflistung geändert wird, kommt
    System.InvalidOperationException: "Die Sammlung wurde geändert. Der Enumerationsvorgang kann möglicherweise nicht ausgeführt werden."
    Spekulatius: Wir suchen immer noch an der falschen Stelle.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    @VaporiZed Die sammlung wurde aber nicht geändert. Das verstehe ich ja auch nicht. Jetzt läuft das Programm ohne Probleme seit ca. 5std(ca. 6Mil. Rows Abgearbeitet). Und es ist wirklich die Fehlermeldung "Index ausserhalb der Arraybereichs". Darf ja bei einer For Each gar nicht passieren!!!

    Rattenfänger schrieb:

    Darf ja bei einer For Each gar nicht passieren!!!
    Kann es sein, dass sich in der Datenbank was verändert hat?
    Ich hab mal was konstruiert, da kommt eine ArgumentOutOfRangeException:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private MyList As New List(Of Integer)
    3. Private MyDict As New List(Of Integer)
    4. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    5. For i = 0 To 10
    6. Me.MyList.Add(i)
    7. Me.MyDict.Add(i)
    8. Next
    9. End Sub
    10. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    11. For Each i In MyList
    12. If i = 5 Then
    13. Me.MyDict.Remove(i)
    14. End If
    15. Me.ListBox1.Items.Add(Me.MyDict(i))
    16. Next
    17. End Sub
    18. End Class
    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!
    wie ich in post#8 bereits ausführe: Du hast die "Fehlermeldung" selbst verfasst.

    Das ist, was gar nicht passieren darf: Einen TryCatch machen, und darin eine Fehlermeldung ausgeben, die überhaupt nicht stimmt.
    TryCatch ist ein heißes Eisen

    Immerhin scheints in dem Proggi um Geld zu gehen.
    Und da eine Exception einfach zu catchen, und das Proggi in möglicherweise instabilen Zustand, oder mit falschen Daten weiter laufenzulassen...

    (oder hast du das bereits behoben - nur nicht gesagt?)
    @RodFromGermany Der Code wird erst ausgeführt, wenn alle Änderungen an der Tabelle gemacht wurden. Ich werde es nochmal als Bild senden, wenn es auftritt. Aber ich glaube @Fakiz war schon auf der richtigen Spur, den in der Funktion AddNewInteger hatte ich schon mal einen Fehler, den ich auch mit einem Try Catch abgefangen habe. Und hier sieht man mal wieder, das Ihr wie immer recht hattet, kein Try Catch nutzen :-), den der Fehler wird nur verschoben. :thumbup:

    @ErfinderDesRades das habe ich nur für mich reingeschrieben um zu sehen wie oft er vorkommt und wie gesagt er tritt bei (1,1 Millionen * 3400) zeilen einmal auf. Nur dieses eine mal hat mir die berechnungen von 3std. zerschossen und das ist nervig. Nur möchte ich auch wissen, was da schief läuft, um erstens diesen fehler zu korigieren und natürlich Ihn nicht zu wiederholen.

    Nein hier geht es noch nicht um Geld, das ist nur das Settings Tool, was mir die einstellungen berechnet.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Rattenfänger“ ()