none
Simples VB.NET Programm stürzt ab --WARUM? RRS feed

  • Frage

  • Hi community,

    anbei ein sehr simples VB.NET Programm, welches eigentlich nix sinnvolles macht.

    Leider "stürzt" es bei allen Schleifenwerten >150 ab. Außerdem dauert  die Berechnungszeit bis 100 eine gefühlte Ewigkeit.

    Komm einfach nicht drauf,warum dem so ist. Vielleicht könnt ihr mich aufklären? Aber bitte keine tipps,wie man diesen Code effizienter gestalten könnte.

    Ich will einfach nur wissen,warum bei Schleifen bis 100 gerechnet wird(wenn auch quälend langsam), und bei über 100 nicht mehr...............

    Option Strict On
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Call anzeigen()
        End Sub
        Sub anzeigen()
            Dim a As Int64, b As Int64, c As Int64
            Dim text As String
            text = "Limit erreicht"
            For a = 1 To 100
                For b = 1 To 100
                    c = a * b
                    If c >= 90 * 90 Then
                        ListBox1.Items.Add(text)
                    End If
                    ListBox1.Items.Add(a.ToString)
                    ListBox1.Items.Add(b.ToString)
                    ListBox1.Items.Add(c.ToString)
                Next b
            Next a
        End Sub
    End Class

    Das Python-Pendant arbeitet problemlos, und v.a recht zügig.....


    n=input(n) n=int(n) for a in range(1,n): for b in range(1,n): c=a*b

    if (c>100*100):

    print("Limit erreicht")

    print(a,b,c)

    Also muss der VB.NET Code fehlerhaft sein!!




    • Bearbeitet tklustig Mittwoch, 9. November 2016 20:51
    Mittwoch, 9. November 2016 20:22

Antworten

  • Hallo,

    da ist nichts fehlerhaft, eine GUI Anwendung stellt nur andere Ansprüche als eine Konsolenanwendung.

    Der Kern des Problems ist, dass Du die Listbox mit Aktualisierungen überflutest. Dadurch wird viel Zeit mit der Aktualisierung "verbraten".

    Zum einen solltest Du die Zahl der Elemente wie in Python auf eines reduzieren. denn auch da gibt es Grenzen. Zum anderen kann man über BeginUpdate... EndUpdate die Aktualisierung der Listbox solange stoppen, bis die Ergebnisse vorliegen. Eine mögliche Verbesserung:

        Private Sub ListboxÜberfüllen()
            Dim Text As String = "Limit erreicht"
            Dim limitReached As Boolean = False
            ListBox1.BeginUpdate()
            Try
                For a As Integer = 1 To 100
                    For b As Integer = 1 To 100
                        Dim c As Integer = a * b
                        If Not limitReached AndAlso c >= 90 * 90 Then
                            limitReached = True
                            ListBox1.Items.Add(Text)
                        End If
                        'ListBox1.Items.Add($"{a} {b} {c}")
                        ' oder hübscher
                        ListBox1.Items.Add(New Tuple(Of Integer, Integer, Integer)(a, b, c))
                    Next b
                Next a
            Finally
                ListBox1.EndUpdate()
            End Try
        End Sub
    

    Ein Int64 brauch es definitiv nicht, das Ende einer Listbox wird bereits früher erreicht sein.

    Gruß Elmar

    Donnerstag, 10. November 2016 10:03
    Beantworter

Alle Antworten

  • Hallo,

    da ist nichts fehlerhaft, eine GUI Anwendung stellt nur andere Ansprüche als eine Konsolenanwendung.

    Der Kern des Problems ist, dass Du die Listbox mit Aktualisierungen überflutest. Dadurch wird viel Zeit mit der Aktualisierung "verbraten".

    Zum einen solltest Du die Zahl der Elemente wie in Python auf eines reduzieren. denn auch da gibt es Grenzen. Zum anderen kann man über BeginUpdate... EndUpdate die Aktualisierung der Listbox solange stoppen, bis die Ergebnisse vorliegen. Eine mögliche Verbesserung:

        Private Sub ListboxÜberfüllen()
            Dim Text As String = "Limit erreicht"
            Dim limitReached As Boolean = False
            ListBox1.BeginUpdate()
            Try
                For a As Integer = 1 To 100
                    For b As Integer = 1 To 100
                        Dim c As Integer = a * b
                        If Not limitReached AndAlso c >= 90 * 90 Then
                            limitReached = True
                            ListBox1.Items.Add(Text)
                        End If
                        'ListBox1.Items.Add($"{a} {b} {c}")
                        ' oder hübscher
                        ListBox1.Items.Add(New Tuple(Of Integer, Integer, Integer)(a, b, c))
                    Next b
                Next a
            Finally
                ListBox1.EndUpdate()
            End Try
        End Sub
    

    Ein Int64 brauch es definitiv nicht, das Ende einer Listbox wird bereits früher erreicht sein.

    Gruß Elmar

    Donnerstag, 10. November 2016 10:03
    Beantworter
  • Wieder ma' professionell gelöst.

    Wie codiert man das Pendant für eine Textbox?

    Sofern ich Texbox1.Update()  eingebe, reicht das nicht, zumal der Befehl TextBox1.text.endupdate() so nicht funktioniert.....



    • Bearbeitet tklustig Donnerstag, 10. November 2016 20:36
    Donnerstag, 10. November 2016 19:45
  • Hallo,

    eine TextBox unterstützt so etwas nicht und sie wird tendenziell immer langsamer, da die vollständige Zeichenkette neu erstellt wird - zumal der Garbage Collector mehr zu entsorgen hat.

    Weswegen ich auch die Listbox bereits in einem früheren Beitrag empfohlen habe. Auch dort sollte man immer überlegen wieviel Daten man dort ablegt, deswegen Integer anstatt Int64. Denn im Gegensatz zu einem Konsolenprogramm (wie dem Python Skript) werden die Daten weiter vorgehalten und nicht nach der Ausgabe "vergessen".

    $"{a} {b} {c}"

    ist übrigens nichts weiter als

    String.Format("{0} {1}, {2}", a, b, c)

    und ab VS 2015 verfügbar, siehe Visual Basic .NET - 14 Top Improvements in Visual Basic 14 (dort Nr. 12).

    Gruß Elmar

    Freitag, 11. November 2016 08:05
    Beantworter