Ist das hier eine Endlos-Rekursion im Code?

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Ist das hier eine Endlos-Rekursion im Code?

    Hallo,

    habe hier zwei Methoden, die sich scheinbar gegenseitig aufrufen.
    Der Code ist nicht von mir, die Kommentare hab ich eingefügt, damit ihr seht wie ich es bisher verstehe.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Delegate Sub ListViewAddItem_delegate(ByVal DB As String, ByVal Zeit As String, ByVal ID As String, ByVal Ereignis As String) 'den gibt es nur damit ich die Methode in den nachfolgenden Invoke reinkriege
    2. Private Sub ListViewAddItem(ByVal DB As String, ByVal Zeit As String, ByVal ID As String, ByVal Ereignis As String)
    3. Try
    4. If Me.ListView1.InvokeRequired Then ''Invoked wird, weil die Methode manchmal aus einem SerialPort-Thread aufgerufen wird
    5. Dim d As New ListViewAddItem_delegate(AddressOf ListViewAddItem)
    6. Me.ListView1.BeginInvoke(d, Zeit, DB, ID, Ereignis) ''Sehr komisch ist, dass hier die Einträge DB und Zeit vertauscht sind, das ist doch falsch, oder wie funktioniert das? Und dann ruft es sich selbst auf aber ist dann im Thread des ListViews
    7. Else
    8. Dim lvi As New ListViewItem(Zeit)
    9. lvi.SubItems.Add(DB)
    10. lvi.SubItems.Add(ID)
    11. lvi.SubItems.Add(Ereignis)
    12. ListView1.Items.AddRange(New ListViewItem() {lvi})
    13. ListView1.Update()
    14. End If
    15. Catch ex As Exception
    16. fehlereintrag(ID, ex.Message) 'das ruft diese Methode hier auf
    17. Exit Sub
    18. End Try
    19. End Sub
    20. Sub fehlereintrag(ByVal strpistol_id As String, ByVal Fehler As String)
    21. Dim DB As String = "MSSQL"
    22. Dim Zeit As String = CStr(Now)
    23. Dim ID As String = strpistol_id
    24. Dim Ereignis As String = Fehler
    25. ListViewAddItem(Zeit, DB, ID, Ereignis) 'hier springt er in die Methode, die wieder hier reinspringen kann.
    26. End Sub


    Hab ich das richtig erkannt? Natürlich müsste der Catch immer wieder ausgelöst werden, kann das überhaupt?

    Viele Grüße
    @Haudruferzappeltnoch Diese Art des Aufrufs ist mir suspekt, möglicherweise soll das so was wie ein On Error Resume Next nachbilden.
    ====
    Wenn Du im Exception-Zweig (bei Catch) einen Haltepunkt rein setzt, kannst Du das austesten.
    Vielleicht solltest Du rauskriegen, unter welchen Bedingungen da eine Exception auftritt und das ggf. versuchen zu verhindern.
    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!
    Da wird ja gleich an 2 Stellen Zeit und DB vertauscht: Zeile#6 und #26.
    Zeile#17 kann weg.
    Welche Exception kann da eigentlich kommen?
    Den Delegaten kann man eigentlich entfernen, sollte so auch gehen:

    VB.NET-Quellcode

    1. If Me.ListView1.InvokeRequired Then
    2. Me.ListView1.BeginInvoke(Sub() ListViewAddItem(d, Zeit, DB, ID, Ereignis))


    ##########

    Der Fehlerbehandlungscode ist ziemlich besch…aulich. Es werden eben vermeintliche Defaultparameter gesetzt - in der Hoffnung, dass es damit immer klappt - "default" eben.
    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.

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

    VaporiZed schrieb:

    Da wird ja gleich an 2 Stellen Zeit und DB vertauscht: Zeile#6 und #26
    Ahh, dadurch hebt sich das weg, ich hab mich schon gewundert warum alles korrekt aussieht.

    Ich konnte das Programm bisher nicht debuggen. Das muss ich noch erst in Gang kriegen.

    Dass da überhaupt eine Exception auftritt ist die Frage, ich konnte bei den Add und AddRange -Methoden keine Exceptions finden.

    Angenommen sie tritt tatsächlich auf, würde sich das Programm dann aufhängen oder wie bemerkt man das?
    Ich würde dieses ganze InvokeRequired-Geschwurbel entfernen.
    Der TryCatch ist auch Nonsense - ich wüsste nicht, was da schief laufen kann, wenn einem Listview ein Item zugefügt wird.
    Und wenn das tatsächlich schief läuft, dann aufgrund eines so gravierenden Programmier-fehlers, dass der Retry im Trycatch sicher auch fehlschlägt.
    Und damit hat man eine Endlos-Rekursion, die in einen noch viel dolleren Absturz führt: StackOverflow.

    Wo schnappt man solche Schwurbel-Codes auf, und warum setzt man sich damit auseinander?

    Also um die im Titel gestellte Frage zu beantworten:
    Das ist kein "Loop im Code" - weil "Loop" ist eine Schleife - keine Rekursion.
    Es sind sogar zwei rekursive Aufrufe: Einmal ruft die Methode sich selber auf bei InvokeRequired, und zum anderen beim Catch.
    Die Catch-Rekursion ist ein bischen obfuskiert, weil die Methode ruft sich nicht direkt selber auf, sondern ruft eine andere Methode, die dann wieder die erste aufruft.
    Diese Catch-Rekursion ist besonders verheerend, weil im Fehlerfall ruft die Methode sich (indirekt) selber auf, erzeugt einen weiteren Fehler, ruft sich dann selber auf, erzeugt einen weiteren Fehler, etc... bis bäng.

    Also ich vermute, mit "Loop im Code" meinst du vielleicht "Rekursion", vielleicht sogar "Endlos-Rekursion".
    Und - ja - isses, und ja: ist sehr problematisch, und gut, dass dir auffällt, dass da was faul ist - sogar ohne, dass du die Begriffe dafür kanntest.

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

    Dass da ein Fehler auftritt, würdest Du daran sehen, dass die Default-Parameter im ListView stehen und nicht Deine vorgegebenen. Das bedeutet im gröbsten Fall: Datenverfälschung. Danke, ich verzichte darauf. Wie EdR schrieb: Weg mit dem Fehlerbehandlungscode. Wir reden darüber, wenn wirklich ne Exception auftritt.
    @ErfinderDesRades: Ich tippe auf übernommene Altlasten eines Programmiervorgängers. <X Aber wenn der Code - wie in den Kommentaren beschrieben - auch nebenläufig aufgerufen werden könnte, sehe ich keinen Grund, das Invoke zu entsorgen
    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.
    Ich habe einen ganzen Haufen solcher Codes^^

    Ich baue die um in etwas weniger schwurbelig, damit konnte ich bisher viel lernen.
    Denn diese Programme funktionieren an sich schon, auch wenn es manchmal etwas hackelig ist.

    Gerade deswegen finde ich das gut zum lernen, weil man sich viel mehr in der Codelogik eingraben muss.
    Mit solchen Codesorten hab ich zum Glück nur ein wenig zu tun. Denn der größte Bockmist, den ich zu Gesicht bekomme, ist der Code, den ich selbst vor mehreren Jahren geschrieben habe - in Vor-Forums-Zeiten. Ich vermute daher stark, dass Deine "einzig valide Unperformancezahl" höher ist als meine - weil ich mich in mein altes ich zurückversetzen kann :P
    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.
    Ich besitze keine VB expertise daher kann ich nicht viel dazu sagen.
    Aber im Falle das es noch nicht genannt wurde, diese Art der Rekursion nennt dich "Indirekte Rekursion", bei welcher zwei Funktionen sich gegenseitig immer wieder aufrufen.
    Es gibt Anwendungsgebiete dafür.

    Das hier sieht mir aus wie eine Log-Queue, wo Log-Texte gespeichert werden für spätere Ausgabe und wenn das Speichern eines Fehlers versagt ein neuer hinzugefügt wird.
    Wirkt sehr komisch auf mich wie das hier gehändelt wird.
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------