Windows Forms Start-Cancel-Button

  • VB.NET

Es gibt 40 Antworten in diesem Thema. Der letzte Beitrag () ist von MichiGee.

    MichiGee schrieb:

    und wir testen des einfach im größeren Stil
    Also mal ganz einfach:
    Wie lautet die Aufgabenstellung?
    Gib mal ein paar Details zu Deiner geplanten Umsetzung, ohne eine Lösung vorwegzunehmen.
    Wo liegt das Problem?
    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!
    Die auufgabenstellung lautet: Strukruroptimierung von Gitterschalen mit Hilfe von Rfem/Rstab.

    Mein Problem : ich führe die Main prozedur aus und meine Windows Form freezed. Ich will einen knopf einbauen, das ich auf abbrechen klicken kann ohne den Task Manager zu öffnen ;)
    und - nach deiner Angabe - das Freezen liegt am Datentransfer zu einem anneren Programm via Com / R232 / R2D2 - was auch immer, jdfs. wohl kein SerialPort.

    Und unklar - aber für Threading von entscheidender Bedeutung - ob der Datentransfer nur ein Einlesen-Verarbeiten-Zurückschreiben ist, oder ob da eine dichtere Kommunikation stattfindet.
    Du hast auch schon hunderte Codezeilen gezeigt, aber nix vom Einlesen und Wegschreiben.

    naja - egal - an inhaltlicher Untersuchung nach VerbesserungPotential wohl nicht interessiert - schreit nur noch nach seim Knopf zum Abbrechen.
    Nun ist das auch nicht so einfach, deswegen machen wir ja son Heckmeck drumrum.
    Du willst vmtl. auch eine Progressbar, damit der User sieht, was läuft, und der Abbrechen-Button darf nur während des Laufes funktionieren, und der Startbutton darf während des Laufes grade nicht funktionieren, und dafür, dass der User das Prog einfach schließt während des Laufes musst du auch noch was einbauen.

    All diese Probleme im Zusammenhang behandelt und gelöst sind hier : AsyncWorker - CodeProject

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

    MichiGee schrieb:

    Mein Problem
    ist, dass Du Dein Problem nicht so beschreiben kannst, dass wir Dir optimal helfen können.
    Ich erkenne in Deinen Worten keinerlei Zusammenhang zwischen FEM und dem Freezen der Form.
    Geht es ein wenig detaillierter?
    Wer macht was?
    Wo werden die FE bereitgestellt?
    Wo wird gerechnet?
    Wo wird angezeigt?
    ...
    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!
    Ja scheinbar kann ich euch nicht richtig vermitteln woran mein Problem liegt.

    Die entsprechende Codezeile zum Wegschreiben ist hier:

    VB.NET-Quellcode

    1. Idata.rfGetNode(rfnode(i_n).iNo, ITEM_AT.AT_NO).rfSetData(rfnode(i_n))

    Und diese ist durch die Schnittstelle vorgegeben!
    Also ich definiere mir einen Node (Eigene Klasse) und einen RFnode (RFEM-Klasse) und sage dann RFnode = Node
    Die Aufteilung habe ich gemacht da ich das Input File sowie das Endergebnis als XML-Datei speichern möchte. (Wird mit XML-Serializer erledigt)
    Außerdem muss ich dann nicht ständig auf die Lizenz zugreifen, kann alles in Arrays speichern und schreibe sämtliche Strukturdaten in einem Aufwisch zu RFEM rüber.

    Klar bin ich prinzipiell an einer Optimierung meines Codes interessiert, aber ich habe mich wohl unglücklich ausgedrückt mit dem "Schreiben an das Programm dauert lange".
    Habe mal nen Timer eingebaut: Das Updaten der Struktur dauter ca. 1-3ms. Also was wirklich dauert ist natürlich jedes mal die FE-Berechnung und das liegt am FE-Programm.

    Warum ich so nach diesem Button schreie ist folgendes Problem.
    Ich gehe in Debug-Modus, weil ich für den Optimierungsalgorithmus was neues geschrieben habe und möchte es testen.
    Wenn ich jetzt max. 20 Iterationsschritte eingestellt habe aber irgendwas nicht stimmt, muss ich entweder die 20 Schritte abwarten oder auf Stop Debuggen drücken.
    Dabei wird dann durch

    VB.NET-Quellcode

    1. IStructure.rfGetApplication().rfLockLicence()

    Die Lizenz des FE-Programms gesperrt und ich habe einen offenen Prozess --> Task Manager öffnen und FE-Programm schließen...und das nervt!!!
    ich will also währende des Laufens auf abbrechen drücken können, mein Programm springt dann zur Code-Zeile

    VB.NET-Quellcode

    1. IStructure.rfGetApplication().rfunLockLicence()
    2. '...Speichere alles, schreibs in ein XML und gib alles frei...was auch immer danach noch kommt

    MichiGee schrieb:

    Habe mal nen Timer eingebaut: Das Updaten der Struktur dauter ca. 1-3ms.
    Du hast keinen Timer eingebaut, allenfalls eine StopWatch. Ein Timer ist ein Taktgeber, kein Zeit-messinstrument.
    und 1-3ms kann auch problematisch sein, wenns 10000 mal aufgerufen wird - wie oft wirds im Gesamtvorgang aufgerufen?

    naja egal - ich nehme nun an, dass der Zeitfresser die Methode Optimization() ist, wenn die 1000 Iterationen oder sowas durchführt.
    Kann man in einen Nebenthread verlagern, aber vorher muss man noch eine klassenweite Boolean Variable "IsRunning" deklarieren, wo er pro Iteration nachguckt, ob die noch an ist - wenn nicht, dann Methode verlassen.
    Aber das ist der Krepel-Ansatz, den du nirgends abliefern kannst, weil die Progressbar fehlt, und die aktivierung/deaktivierung der Start/Stop-Buttons, und das stürzt ab, wenn der User vorher schließt.

    Also wie willst du vorgehen: Krepel-Ansatz, oder gleich richtig mittm AsyncWorker?
    @MichiGee Wie läuft denn das ganze ühaupt ab?
    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!
    Also der Ansatz ist mir eigentlich egal, so einfach wie möglich, so kompliziert wie nötig.

    @RodFromGermany was meinst wie das abläuft?

    Also Programmaufbau ist in etwa so:
    Ich erstelle eine Struktur in RFEM
    Über meine MainForm habe ich ein paar Eingabeparameter z.b. woher die Struktur kommt, wohin sie gespeichert werden soll, wie groß der Fehler sein darf etc.
    Dann lese ich die Struktur aus, lasse sie rechnen und lese die Schnittgrößen aus.
    Dann bilde ich einen Gradienten mit Finiten Differenzen (also eine quasi Ableitung, da ich die Steifigkeitsmatrizen nicht aus dem Programm bekomme)
    Setze den negativen Gradienten als Suchrichtung, bestimme die Schrittweite und Update die Struktur.
    Das ganze Iteriere ich bis ein optimales Ergebnis gefunden wird.

    Wie bereits klar ist rufe ich das über die Main Prozedur auf.
    also Krepel-Ansatz, mittm Backgroundworker.
    Zieh einen Backgroundworker aus der Toolbox aufs Form. Doppelklickse drauf.
    Poste die generierte BW-Methode, und ausserdem die ButtonClick-Methode, mit der der Vorgang gestartet wird.
    Ach, und poste den ButtonClick vom Cancel-Button auch!
    Also 3 Methoden musste posten, von denen 2 leer sind, nur die btStart_Click-Methode, da wird ja was drinne stehen.

    Da muss man das einbauen

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

    @MichiGee Wenn Du Probleme mit dem Tip vom @ErfinderDesRades hast, mach zunächst einen Ansatz, wo Du jeden einzelnen Schritt in eine separate Button_Click-Prozedur baust.
    Die sortierst und zusammenfasst Du so, dass nicht 2 Klicks ohne zwingende Eingabe nacheinander kommen.
    Das, was nun in der Prozedur steht, die am lüngsten dauert bzw. die unterbrochen werden können soll, packst Du in die BackgroundWorker-DoWork-Prozedur.
    Dann sehen wir weiter.
    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!
    Ok, dann mal hier die Schnipsel und vielen Dank im Voraus:
    Ich könnte natürlich auch die Sub Main direkt in Button1_Click packen, falls des besser wäre..?
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bttn_start.Click
    2. Main()
    3. End Sub
    4. Private Sub bttn_close_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bttn_close.Click
    5. Me.Close() 'Close Programm
    6. End Sub
    7. Private Sub BGWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGWorker.DoWork
    8. End Sub

    ein Versuch - testen kann ich ja nix

    VB.NET-Quellcode

    1. Private Sub bttn_Abort_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bttn_Abort.Click
    2. BGWorker.CancelAsync()
    3. End Sub
    4. Private Sub BGWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGWorker.DoWork
    5. Main()
    6. End Sub
    7. Private Sub bttn_start_Click(sender As System.Object, e As System.EventArgs) Handles bttn_start.Click
    8. BGWorker.RunWorkerAsync()
    9. End Sub
    10. Sub Optimization(ByRef folder As String, ByRef MaxIterations As Integer, ByRef epsilon As Double, ByRef alpha As Double, _
    11. ByRef delta As Double, ByRef OptiMethod As String, ByRef txt_box As TextBox, ByRef txt_CostFunction As TextBox, _
    12. ByRef Istructure As IrfStructure, ByRef Idata As IrfStructuralData, ByRef Ires As IrfResults, ByRef Structurename As String)
    13. '...
    14. '... dein code
    15. For k = 2 To MaxIterations
    16. If BGWorker.CancellationPending Then Return
    17. '...
    18. '... dein code
    19. Next
    20. '...
    21. '... dein code
    22. End Sub
    zu beachten zeile#19, wo geguckt wird, ob abgebrochen werden soll.

    MichiGee schrieb:

    ich des ganze Ding schließen kann.
    Aber die Daten gespeichert hast Du da schon?
    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!
    Ja daten sind dann schon gespeichert und alles.
    Haltepunkte sind mir durchaus bewusst, aber ich werde mir des Video trotzdem mal anschauen...danke

    Hänge grad noch kurz an der Übergabe von den Variablen aus der Form in die Main() , sollte ich aber gleich hinbekommen...

    MichiGee schrieb:

    Übergabe von den Variablen
    Nimm Properties oder raise ein Event.
    Gugst Du hier.
    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!
    Des mit den Properties hatte ich schnell raus, trotzdem danke. Konnte dann nur nicht mehr in der "Main-Form" in die Texboxen schreiben, aber halb so wild.
    Läuft jetzt so weit ganz gut. Vielen Dank.
    Habe so lange nichts geschrieben, da ich in der Übergabe auf etwas gestoßen bin was mich ein bisschen mehr ärgert ;)

    Bekomme Stringlisten von Knoten z.B. "1,2,6-8,10" und brauche des ganze als Integer
    Wäre den String jezt abgelaufen, hätte ihn mit "," in n Array aufgesplittet und die 6-8 hochzählen lassen und über ReDim Preserve ans Ende des Arrays gepackt. Nicht schön aber funktioniert (glaub ich ;) )

    Lg

    MichiGee schrieb:

    ReDim Preserve
    ist VB6-Grütze.
    Nimm eine New List(Of Integer), da kannst Du Items hinten dran adden oder sonst wo einfügen.
    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!