Berechnungsprogramm durch Button abbrechen

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    Berechnungsprogramm durch Button abbrechen

    Hallo alle miteinander,

    Leider bin ich VB-Laie und komme bei einer Abänderung meines Berechnungsprogramms nicht weiter.
    Folgendes Problem:
    Aus ca. 20 Textboxen werden über ein Unterprogramm mehrere Werte ermittelt.
    Das Unterprogramm funktioniert auch einwandfrei, solange die Eingabewerte in den Textboxen realistisch sind.
    Wenn aber unrealistische Werte eingegeben werden iteriert sich das Unterprogramm zu Tode und die ganze Software hängt sich auf.
    Nun die Frage:
    (1) Gibt es (einfache) Möglichkeiten, einen Abbruch per button hervorzurufen?
    (2) Oder ist es möglich, einen Abbruch der Berechnung nach z.B. 10 Sekunden zu erzwingen?
    Vielen Dank im Voraus

    Coco123
    1.:
    For i = 1 to integer.maxvalue
    ...
    if ExternalBoolAlsSemaphore = True then exit for

    2.:
    Dim stp as new stopwatch
    stp.start
    For i = 1 to integer.maxvalue
    ...
    if stp.elapsedseconds > irgendwas then exit for

    EDIT:
    3.:
    Berechnung in Thread auslagern und den killen/beenden per Button oder Timer

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Public Class Form1
    3. Private t As Thread
    4. Private Sub foo()
    5. Do
    6. ' rödel rödel rödel bis das Universum ended
    7. Loop
    8. End Sub
    9. Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    10. If t Is Nothing OrElse Not t.IsAlive Then
    11. t = New Thread(AddressOf foo)
    12. t.IsBackground = True
    13. t.Start()
    14. Else
    15. MessageBox.Show("läuft schon!")
    16. End If
    17. End Sub
    18. Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
    19. If t Is Nothing OrElse Not t.IsAlive Then
    20. MessageBox.Show("läuft doch gar nicht!")
    21. ElseIf t.IsAlive Then
    22. t.Abort()
    23. End If
    24. End Sub
    25. End Class

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

    Danke für die schnelle Antwort!

    Werde ich gleich mal ausprobieren.

    Gruß
    Coco123
    Wenn ich deine dritte Variante versuche habe ich das Problem, dass ich keine Buttons mehr drücken kann, weil das Programm lädt und lädt und lädt, bis es nicht mehr antwortet. Was mach ich falsch?

    VB.NET-Quellcode

    1. Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click If t Is Nothing OrElse Not t.IsAlive Then MessageBox.Show("läuft doch gar nicht!") ElseIf t.IsAlive Then t.Abort() End If End Sub




    Habe noch Folgendes probiert:

    VB.NET-Quellcode

    1. Dim stp As New Stopwatch
    2. stp.Start()
    3. Do
    4. Call Berechnung.Start() 'Dieses Unterprogramm läuft sich zu Tode
    5. If stp.ElapsedMilliseconds > 10000 Then
    6. Exit Do
    7. End If
    8. Loop


    Jedoch hab ich das Problem, dass er die Zeit nicht hochzählt, solange "Berechnung" noch läuft. Was könnte ich noch tun?

    Mir würde auch ein Programmabbruch ohne Bestätigung durch einen Button reichen...

    Gruß

    Edit by der_Kurt:
    Doppelposts sind nicht gestattet
    * Beiträge zusammengefügt *

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „der_Kurt“ ()

    Das mit dem Threading hab ich auch schon probiert. Jedoch kann ich keinen button mehr drücken, wenn die Berechnungsfunktion läuft.

    Da die Berechnungsfunktion aus vielen Schleifen besteht kann ich schwer voraussagen, welche Schleife divergiert. Deswegen wollte ich es vermeiden, Abbruchkriterien in der Berechnungsfunktion einzufügen.

    Ich habe mir das so vorgestellt:
    Wenn "Berechnung" läuft und es länger als 10 Sekunden benötigt, soll es beendet werden.

    Ist das so zu realisieren?

    Gruß

    coco123 schrieb:

    Ist das so zu realisieren?

    Ja. MIT THREADING.
    Das Beispiel dazu habe ich doch oben gegeben.
    Wenn du ANGEBLICH threading ausprobiert hast und du keinen Button mehr drücken konntest, dann hast du wohl KEINEN thread erzeugt, sondern hast fröhlich um UI Thread gerechnet und den damit völlig lahmgelegt.
    Hatte anscheinend doch irgendwas falsch gemacht. Jedenfalls habe ich es endlich hinbekommen, die Berechnung mittels Threading abzubrechen.
    Allerdings ist jetzt eine neue Schwierigkeit entstanden, den Input aus den Textboxen an den neuen Thread bzw. dann weiter an die Berechnung weiterzugeben. Was mach ich falsch?


    VB.NET-Quellcode

    1. Private Sub foo()
    2. Do
    3. Call Berechnung.Start()
    4. Loop
    5. End Sub
    6. Private Sub btnstart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnstart.Click
    7. Wert1 = Wert1.Text
    8. If t Is Nothing OrElse Not t.IsAlive Then
    9. t = New Thread(AddressOf foo)
    10. t.IsBackground = True
    11. t.Start()
    12. Else
    13. MessageBox.Show("läuft schon!")
    14. End If
    15. End Sub


    Im Unterprogramm Berechnung habe ich mir die Daten so geholt:

    VB.NET-Quellcode

    1. Sub Start()
    2. ' Eingabedaten holen von frmHaupt
    3. Wert1 = frmHaupt.Wert1
    4. ...
    5. End Sub

    Pack alle Werte als Eigenschaft in eine eigene Klasse und übergebe die Klasse als Parameter, weil so kannst du jederzei die Klasse erweitern und musst nicht mehr Parameter erstellen.
    Die Textboxen zum Einlesen der Daten befinden sich in meiner "Haupt"-Klasse. Wenn ich eine neue Klasse erstelle, kann ich ja nicht mehr meine Textboxen abrufen. Zumindest weiß ich nicht, wie ich es umsetzen kann.
    Gemeint war das so:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim t As Threading.Thread
    3. Private Sub Start '...
    4. t = New Threading.Thread(AddressOf Foo)
    5. t.IsBackground = True
    6. t.Start(New ParameterClass With {.TextBox1_Text = TextBox1.Text, .TextBox2_Text = TextBox2.Text})
    7. End Sub
    8. Private Sub Foo(ByVal ObjectParameter As Object)
    9. Dim Parameters As ParameterClass = DirectCast(ObjectParameter, ParameterClass)
    10. For Each i As Char In Parameters.TextBox1_Text
    11. 'Mit den Parametern aus Parameters arbeiten
    12. Next
    13. End Sub
    14. End Class
    15. Public Class ParameterClass
    16. Public TextBox1_Text As String
    17. Public TextBox2_Text As String
    18. '...
    19. 'Alle benötigten Dinge hier zwischenspeichern
    20. End Class


    Wobei ein BackGroundWorker möglicherweise besser für dieses Unterfangen geeignet ist, weil er nicht mit Delegaten arbeiten muss (intern sicherlich schon, aber der Coder bekommt davon nichts mit).
    Das Übergeben der Parameter an den Thread ist hier schön einfach, aber die Ergebnise wieder in den UI Thread zu bringen dürfte schwieriger werden, wenn man es mit System.Threading.Threads macht.

    Falls Du mit einem BackGroundWorker arbeiten möchtest: Dieses Tutorial könnte Dir weiterhelfen (*Eigenwerbung mach ^^*).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils