Windows Forms Start-Cancel-Button

  • VB.NET

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

    Windows Forms Start-Cancel-Button

    Hallo Leute,

    ich schreibe gerade an meiner Masterarbeit (Bauingenieurwesen) ein Optimierungsprogramm.
    habe mir jetzt eine kleine Windows Forms Anwendung dazu erstellt.
    Im Wesentlichen habe ich da ein paar Eingabeparameter und Checkboxes bzw. Radiobuttons und das wichtigste einen Start und einen Close Button.
    Das ganze sieht dann so aus wie im Anhang.

    Wenn ich jetzt auf start klicke werden meine Prozeduren und Funktionen etc. aufgerufen und Text ausgegeben
    in etwa so.

    VB.NET-Quellcode

    1. Public Sub bttn_start_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bttn_start.Click
    2. bttn_close.Text = "Cancel"
    3. bttn_close.Enabled = True
    4. Main() 'hier werden verschiedene Klassen mit Prozeduren und Funktionen aufgerufen.
    5. End Sub


    Mein Problem ist jetzt natürlich, dass während der Ausführung die Start-Taste "gedrückt" ist und die komplette Anwendung gefroren ist.
    Würde jetzt gerne einfach einen Cancel Button einbauen um während der Ausführung des Programms das ganze abbrechen zu können.

    Habe auch schon einiges über Backgroundworker etc gelesen, hatte aber eigentlich gehofft etwas in etwa wie folgendes zu machen und das Problem zu lösen.

    Wenn der Button gecklickt wird (z.b. ne Boolean-Abfrage einbauen)
    Dann me.cancel

    oder so. Also etwas relativ einfaches, es soll auch niemand während das Programm rechnet was ändern, sondern nur abbrechen.
    Habt ihr da eine Lösung für mich, würd mich freuen.
    Nicht das dass jetzt hier falsch rüberkommt, aber des zählt 0,00 für meine Masterarbeit, mein Betreuer wäre auch mit einer Konsolenanwendung zufrieden ;)

    P.s. Mit Application.Dowork() funktioniert es leider nicht
    Da es sich um einen Code im Rahmen einer Master Thesis handelt und ich programmieren nie gelernt habe, bitte nett bleiben ;)

    Danke
    Lg Michi
    Bilder
    • Winform.PNG

      37,08 kB, 531×470, 164 mal angesehen
    Du müsstest dich dafür mit Threading beschäftigen (gibt viele gute Artikel im Internet darüber, einfach mal googeln). Ein wichtiger Tipp zum Thema noch: CheckForIllegalChrossThreadCalls = False​ ist ein nogo.
    Willkommen im Forum. :thumbup:
    Lagere

    MichiGee schrieb:

    VB.NET-Quellcode

    1. Main()
    in einen Thread aus.
    Beim Drücken des Cancel-Buttons setzt Du ein Flag, das Du in Deiner Prozedur gelegentlich / regelmäßig abfragen musst, um die Prozedur sinnvoll zu beenden.
    Du kannst den Thread auch mit dem Holzhammer beenden, das ist allerdings kein guter Stil.
    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!
    oder zeig mal die Funktionen, die soviel Zeit in Anspruch nehmen.
    Es ist nämlich nicht ausgeschlossen, dass man die so schnell kriegt, dass da nix mehr einfriert.
    Das sollte das erste sein, was man versucht, weil Threading erweist sich immer wieder als doch vertrackter als es anfangs aussieht.
    Das wird leider nichts bringen, da ich ein Optimierungsprogramm schreibe mit Hilfe eines kommerzielen Stabwerkprogramms.
    Und ich bilde mittels Finite Differenzen, Ableitungen, und das ganze in für n-Iterationsschritte.

    Pseudocode:
    Ich lese eine Struktur ein (aus XML bzw. dem Stabwerkprogramm)
    Lasse das Stabwerkprogramm rechnen und mir die Schnittgrößen ausgeben.
    Verändere die einzelnen Designvariablen nacheinander (z.b. z-Koordinate um z+delta) und lasse mir wieder die Schnittgrößen ausgeben.
    Und bilde somit die Ableitung.

    Da ich das für viele Variablen mache und für n-Iterationsschritte friert während der gesamte Prozedur meine Windows Form.

    Werde das mit dem Threadening einfach mal probieren.

    Oder kann ich das ganze einfach irgendwie auslagern?

    MichiGee schrieb:

    irgendwie auslagern?
    In einen Thread.
    Allerdings solltest Du da eine Abbruch-Abfrage einbauen, dass Du ihn geordnet beenden und die Daten speichern kannst.
    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 ohne die Algos mal anzugucken kann man natürlich nix sagen.

    oder nur ganz allgemeine allgemeinPlätze:
    viele performance-Sündenwerden bei String-Verarbeitung begangen, bei Array-Deklarationen und beim Suchen in Auflistungen.
    Diese Liste ist unvollständig.

    beachte #3 der Rules Of Optimization
    d.h. finde den Code-Abschnitt, wo er 95% der zeit verbrät, und stelle erstmal sicher, dass dieser Teil effizient gecodet ist.

    Vorher kein Threading (was das Grauen nur verschleiert, oder gar neues Grauen heraufbeschwört ;) ).
    Eine COM-Schnittstelle kann etwas anderes mit einer TypeLibrary ansteuern.
    In Visual Studio über Projekt-->Verweis hinzufügen --> COM

    Ich schreibe Daten vor allem in die Klasse Node, die neue Geometrie wird in RFEM geladen, die neuen Schnittgrößen werden berechnet und dann lese ich diese wieder aus.

    Der Main-Teil

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Sub Main()
    2. '// Timer
    3. Dim start, ende As Date
    4. Dim timer As New Stopwatch
    5. timer.Reset()
    6. timer.Start()
    7. start = Now
    8. lbl_start.Text = start
    9. '// Text from Input
    10. Dim folder As String = Txt_browser.Text
    11. Dim MaxIterations As Integer = CInt(txt_maxIt.Text)
    12. Dim epsilon As Double = CDbl(txt_epsilon.Text)
    13. Dim alpha As Double = CDbl(txt_alpha.Text)
    14. Dim delta As Double = CDbl(txt_delta.Text)
    15. Dim structurename As String = txt_structurename.Text
    16. Dim optimethod As String = comboOptiMethod.SelectedItem
    17. Txt_Box.Clear()
    18. '// Class Data
    19. 'Dim data As New Data
    20. '''''''''''''''''''''''''''''''''''''''''''''''''''
    21. ' Opti
    22. '''''''''''''''''''''''''''''''''''''''''''''''''''
    23. Dim opti As New GradientOpti
    24. '// Optimization with RFEM-Structure
    25. If bttn_RFEM.Checked = True Then
    26. Txt_Box.AppendText("------------------------------------------------------------" & vbCrLf & _
    27. "Loading Structure from RFEM" & vbCrLf & _
    28. "------------------------------------------------------------" & vbCrLf)
    29. data.RFGetStructure(folder)
    30. data.RFGetLoads(folder)
    31. data.CreateNewStructure(structurename, folder, MaxIterations, epsilon, alpha, delta, optimethod, Txt_Box, txt_CostFunction)
    32. ElseIf bttn_XML.Checked = True Then
    33. Txt_Box.AppendText("------------------------------------------------------------" & vbCrLf & _
    34. "Loading Structure from XML" & vbCrLf & _
    35. "------------------------------------------------------------" & vbCrLf)
    36. data.CreateNewStructure(structurename, folder, MaxIterations, epsilon, alpha, delta, optimethod, Txt_Box, txt_CostFunction)
    37. End If
    38. 10:
    39. 'Release RFEM and Clean Garbage
    40. IStr = Nothing
    41. System.GC.Collect()
    42. '______________________________________________________________________________________
    43. timer.Stop()
    44. ende = Now
    45. lbl_finished.Text = ende
    46. Dim ts As TimeSpan = Timer.Elapsed
    47. ' Format and display the TimeSpan value.
    48. Dim elapsedTime As String = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10)
    49. lbl_calctime.Text = elapsedTime
    50. bttn_close.Text = "Close"
    51. End Sub



    Bei "Createnewstructure" wird eine Übergabe gestartet und springt dann in die Optimization Prozedur

    Das ist der Optimierungsteil des Codes, dieser hat noch Klassen für XML und die Übergabe an RFEM..

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub Optimization(ByRef folder As String, ByRef MaxIterations As Integer, ByRef epsilon As Double, ByRef alpha As Double, _
    2. ByRef delta As Double, ByRef OptiMethod As String, ByRef txt_box As TextBox, ByRef txt_CostFunction As TextBox, _
    3. ByRef Istructure As IrfStructure, ByRef Idata As IrfStructuralData, ByRef Ires As IrfResults, ByRef Structurename As String)
    4. '-------------------------------------------------------
    5. '// 1. INPUT
    6. '------------------------------------------------------
    7. '// Get Structure from XML
    8. Dim MyStr As MyStructure = XMLGetStructure(folder)
    9. Dim RefStr As RefStructure = MyStr.RefStructure(0)
    10. '// Dim Update Structure
    11. Dim UpdateStr As New MyStructure
    12. Dim Str(0) As UpdateStructure
    13. Str(0) = New UpdateStructure
    14. '// Get Design-Variables
    15. Dim i As Integer 'Count Variables
    16. Dim count_n As Integer = RefStr.Node.Count
    17. Dim Node(count_n - 1) As Nodes
    18. Dim rfn(count_n - 1) As RF_NODE
    19. For i = 0 To count_n - 1
    20. ' Save Nodes from XML in my Nodes -- Neccessary to Update the Structure
    21. Node(i) = New Nodes
    22. Node(i).nr = RefStr.Node(i).nr
    23. Node(i).x = RefStr.Node(i).x
    24. Node(i).y = RefStr.Node(i).y
    25. Node(i).z = RefStr.Node(i).z
    26. Next i
    27. Dim count_s As Integer = RefStr.NodeSupport.Count
    28. 'Settin Designvariables (-1 = support, 1 = dof)
    29. Dim x((count_n * 3) - 1) As Double
    30. x = opti.Designvariables(x, count_s, count_n, RefStr)
    31. ' Restrictions
    32. Dim upper As Double = 5
    33. Dim under As Double = -5
    34. Dim xupper(x.Length - 1) As Double
    35. Dim xunder(x.Length - 1) As Double
    36. For i = 0 To x.Length - 1
    37. If x(i) = 1 Then
    38. xupper(i) = x(i) * upper
    39. xunder(i) = x(i) * under
    40. End If
    41. Next
    42. ' End Criterium
    43. Dim eps As Double
    44. '-------------------------------------------------------
    45. '// 2. OPTIMIZATION WITH STEEPEST DESCENT
    46. '-------------------------------------------------------
    47. '// OBJECTIVE FUNCTION f(X)
    48. Dim f As Double
    49. f = opti.ObjectiveFunction(OptiMethod, txt_CostFunction, Istructure, Idata, Ires) 'Objective Function
    50. If f = 0 Then
    51. GoTo 10
    52. End If
    53. '// GRADIENT g(X)
    54. '-----
    55. timer.Reset()
    56. timer.Start()
    57. txt_CostFunction.AppendText("df_i = " & vbCrLf)
    58. '-----
    59. Dim g(x.Length - 1) As Double
    60. g = opti.FDAForward(Node, UpdateStr, Str, x, delta, folder, OptiMethod, txt_CostFunction, f, Istructure, Idata, Ires)
    61. g = opti.NormGradient(g) 'Norm Gradient
    62. '// SEARCH VECTOR:
    63. Dim s(g.Length - 1) As Double
    64. For i = 0 To g.Length - 1
    65. s(i) = -g(i) 'Search Vector as Negative Gradient
    66. Next
    67. '// UPDATE GEOMETRY - AND CALCULATE ALL
    68. UpdateStr = opti.RFGeoPlus(Node, UpdateStr, Str, x, s, alpha, folder, Istructure, Idata) 'First Updated Structure
    69. '// CALCULATE UPDATED GEOMETRY
    70. RFCalculate("All", Istructure, Idata, Ires)
    71. '// PROOF END OF ITERATION
    72. eps = opti.Norm(g)
    73. If eps = 0 Then
    74. GoTo 20
    75. ElseIf eps <= epsilon Then
    76. GoTo 30
    77. ElseIf MaxIterations = 1 Then
    78. GoTo 40
    79. End If
    80. ' Unlock RFEM-License
    81. Istructure.rfGetApplication().rfUnlockLicence()
    82. '-------------------------------------------------------
    83. '// 3. OPTIMIZATION WITH CONJUGATED GRADIENT METHOD
    84. '-------------------------------------------------------
    85. Dim gk(g.Length - 1) As Double 'Dimension Gradient(k)
    86. Dim sk(g.Length - 1) As Double 'Dimension Search Vector(k)
    87. Dim Beta As Double
    88. Dim fk As Double
    89. Dim k As Integer
    90. '// ALGORITHM
    91. For k = 2 To MaxIterations
    92. '// GRADIENT g(X)
    93. Istructure.rfGetApplication().rfLockLicence()
    94. 'Cost Function for every DOF to build Gradient
    95. gk = opti.FDAForward(Node, UpdateStr, Str, x, delta, folder, OptiMethod, txt_CostFunction, fk, Istructure, Idata, Ires)
    96. gk = opti.NormGradient(gk)
    97. '// BETA - Correction Factor
    98. Beta = (opti.Norm(gk) / opti.Norm(g)) ^ 2
    99. '// SEARCH VECTOR: w.r.t BETA
    100. For i = 0 To gk.Length - 1
    101. sk(i) = -gk(i) + Beta * s(i) 'Search Vector * beta
    102. Next
    103. '// LINE SEARCH
    104. alpha = opti.InterpolationPapa(Node, UpdateStr, Str, x, sk, f, folder, OptiMethod, txt_CostFunction, Istructure, Idata, Ires)
    105. '// UPDATE GEOMETRY
    106. UpdateStr = opti.RFGeoPlus(Node, UpdateStr, Str, x, sk, alpha, folder, Istructure, Idata)
    107. '// CALCULATE UPDATED GEOMETRY
    108. RFCalculate("All", Istructure, Idata, Ires)
    109. '// Update Objective Function
    110. txt_CostFunction.AppendText("f_k = " & vbCrLf)
    111. fk = opti.ObjectiveFunction(OptiMethod, txt_CostFunction, Istructure, Idata, Ires)
    112. '// Norm gk
    113. eps = opti.Norm(gk) - 1
    114. '// PROOF END OF ITERATION
    115. If OptiMethod = "Mass" Then
    116. If eps <= epsilon Then 'Abs(f - fk) <= epsilon Or
    117. GoTo 30
    118. End If
    119. Else
    120. If eps <= epsilon Or fk <= epsilon Then
    121. GoTo 30
    122. ElseIf k = MaxIterations Then
    123. GoTo 40
    124. End If
    125. End If
    126. '// Set fk+1 to f & gk+1 to g
    127. g = gk.Clone
    128. f = fk
    129. Istructure.rfGetApplication().rfUnlockLicence()
    130. Next
    131. '// SKIP MARKS - END OF ALGORITHM
    132. 10: 'Objective Function = 0
    133. MsgBox("Objective Function = 0")
    134. Istructure.rfGetApplication().rfUnlockLicence()
    135. Exit Sub
    136. 20: 'Small StepSize or Optimum Reached
    137. MsgBox("Small StepSize")
    138. Istructure.rfGetApplication().rfUnlockLicence()
    139. Exit Sub
    140. 30: 'Converged
    141. MsgBox("Convergence reached after " & k & " Steps", MsgBoxStyle.OkOnly)
    142. Istructure.rfGetApplication().rfUnlockLicence()
    143. Exit Sub
    144. 40: 'Max Iterations
    145. MsgBox("Reached Max. Iterations", MsgBoxStyle.OkOnly)
    146. Istructure.rfGetApplication().rfUnlockLicence()
    147. End Sub
    148. #End Region
    149. End Class



    Daten werden in versch. Funktionen weggeschrieben z.B.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub RFUpdateNodes(ByRef Istructure As IrfStructure, ByRef Idata As IrfStructuralData, ByRef folder As String, ByRef mystr As MyStructure)
    2. ''// RFEM-Structure
    3. Idata = Istructure.rfGetStructuralData()
    4. '// Get Structure from XML and save into My_Structure
    5. Dim Str As UpdateStructure = mystr.UpdateStructure(0)
    6. '// RFEM Modification
    7. Idata.rfPrepareModification()
    8. '//
    9. '// 1. Nodes
    10. '//
    11. '// Checks if Nodes are empty
    12. If Str.Node Is Nothing Then
    13. Else
    14. '// Counts Nodes from XML
    15. Dim count_n As Integer = Str.Node.Count
    16. Dim i_n As Integer
    17. '// Declaration of nodes
    18. Dim node(count_n - 1) As Nodes
    19. Dim rfnode(count_n - 1) As RF_NODE
    20. '// Loop over Nodes
    21. For i_n = 0 To count_n - 1
    22. node(i_n) = New Nodes
    23. rfnode(i_n) = New RF_NODE
    24. node(i_n) = Str.Node(i_n)
    25. rfnode(i_n).iNo = node(i_n).nr
    26. rfnode(i_n).x = node(i_n).x
    27. rfnode(i_n).y = node(i_n).y
    28. rfnode(i_n).z = node(i_n).z
    29. rfnode(i_n).csType = node(i_n).cs
    30. rfnode(i_n).iRefObjectNo = node(i_n).ref
    31. 'Get RFEMNode and update with new Data
    32. Idata.rfGetNode(rfnode(i_n).iNo, ITEM_AT.AT_NO).rfSetData(rfnode(i_n))
    33. Next
    34. End If
    35. '// RFEM Finish Modification
    36. Idata.rfFinishModification()
    37. End Sub



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

    @MichiGee Nur mal so interessehalber:
    Du kommunizierst per RS232 mit einem anderen Computer, in dem die FEM stattfindet? Suboptimaler ginge es kaum.
    Editier bitte Deinen letzten Post, markiere den Quellcode (außerhalb [ vbnet ][ /vbnet ]) und mach einen Spoiler drum.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dein Code
    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!
    nicht mit einem anderen Computer, mit einem anderen Programm.
    Also mein Programm steuert den Solver von RFEM an und ich schreibe Daten und bekomme Daten davon.

    Aber prinzipiell will ich einfach nur meinem Programm einen Abbruch Knopf geben!

    Des Bild ist n Auszug aus der Hilfe, so siehts für VBA aus, funktioniert prinzipiell genauso für VB
    Bilder
    • DlubalCOMStartEN.jpg

      256,34 kB, 1.240×1.754, 137 mal angesehen

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

    Du kommunizierst

    MichiGee schrieb:

    mit einem anderen Programm.
    über RS232?
    Brrrrrrrrrrrrrrrrrrrrrrrr.
    Du musst beim Drücken Deines Buttons ein Flag setzen, das Du in einer inneren Schleife abfragen musst.
    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!
    warum RS232? ich gehe über

    VB.NET-Quellcode

    1. Imports Dlubal.RFEM 'Namespace liegt in ner DLL welche über Verweis hinzugefügt wird!

    Diese Ansteuerung gibt es eben von dem Hersteller und mein Betreuer fand des cool, also mache ich das ;)

    Aber das mit dem Flag klingt ganz gut, mal schauen ob ich des hinbekomme.

    Muchas Gracias

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

    MichiGee schrieb:

    und mein Betreuer fand des cool
    Kommunikation 2er Programme auf einem Rechner über solch? Suboptimalst vom Feinsten.
    Ich nehme mal an, Dein Betreuer hat absolut keine Ahnung und / oder absolut keinen Plan. ;(
    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!