Ausführung auslagern (Asynchron)

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Ausführung auslagern (Asynchron)

    Hallo,

    folgende Sache würde ich gerne umsetzen. Ich habe ein VB.Net Programm, welches Daten von einem SQL Server holt. Fast alle Reporte sind mittels Binding an ein DGV gebunden. Die Ausführung dauert meistens nicht sehr lange, aber ich habe auch Tabellen wo es gerne mal 50t Zeilen sind, auch das dauert vielleicht nur 10 Sekunden. Anders sieht es bei meinem Chart aus, wenn ich hier 10t Zeilen * 16 Variablen habe, braucht es eine Weile, bis alle Areas gefüllt sind. Von Anfang an, habe ich den Fehler gemacht, diese Prozesse nicht asynchron zu starten, so richtig weiß ich auch nicht, wie das geht. Meistens habe ich einen Button, da ist dann die Logik drin, auch setze ich dort Texte in irgendwelche Labels, Zeit der Ausführung, Anzahl der Daten etc. Während der Ausführung ist mein Programm natürlich nicht mehr bedienbar. Jetzt habe ich versucht, das ganze so zu starten, dass es im Hintergrund (asynchron) ausführt und ich weiterhin andere Dinge mit dem Programm machen kann. Das gelingt mir aber nicht, warum weiß ich auch nicht, es kommt halt immer ein Fehler, dass irgendwelche Dinge von einem Hintergrundthread auf ein Steuerelement (wie einem Label) zugreifen. Was wäre der beste Weg, das zu bewerkstelligen? Ich möchte einfach in der Zeit wo die Daten geladen werden, das Programm an anderer Stelle weiter nutzen.

    Thema verschoben; Das Thema wird automatisch dort erstellt, wo man sich befindet, wenn man auf [✱ Neues Thema] klickt. ~VaporiZed

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

    In diesem Falle besser erst garnet mit anfangen, mittm Invoken.
    Man kann eine Methode schreiben, die die Daten holt und als Return-Value returnt.
    Diese Methode kann man async aufrufen - das kann man dir leicht zeigen - wenn die Methode erstmal da ist.
    Die Daten, die die Methode returnt, kann man dann in die Controls bringen, Chart, Grids, Labels etc..
    im Moment führe ich nur diese Dinge in dem Button aus

    VB.NET-Quellcode

    1. Dim StartZeit As Date
    2. Dim StopZeit As Date
    3. Dim Dialog As New frmDialog
    4. Try
    5. Dialog.Show()
    6. Cursor.Current = Cursors.WaitCursor
    7. StartZeit = DateTime.Now
    8. Dialog.Refresh()
    9. Me.GetObjects.ObjectLog.Clear()
    10. DGV.Refresh()
    11. Info.Text = "=== Lese Daten aus der Datenbank ==="
    12. Status.Refresh()
    13. Me.ObjectLogTableAdapter.Fill(Me.GetObjects.ObjectLog, TagList.Text, txtStartTime.Text, txtStopTime.Text)
    14. DATAGRIDVIEW_Sort(DGV)
    15. lblRowInfo.Text = "Es wurden " & DGV.Rows.Count & " Einträge gefunden"
    16. Catch ex As System.Exception
    17. RJMessageBox.Show(ex.Message, "Fehler in Anwendung", MessageBoxButtons.OK, MessageBoxIcon.Error)
    18. Info.Text = "=== ein Fehler ist aufgetreten beim lesen der Daten ==="
    19. Status.Refresh()
    20. End Try
    @RISSN
    Ich habe festgestellt, wenn man vieles in "Try Catch-Blöcken" hat, werden gerade solche "Fehler von VB in der exe-Datei schonmal "unterdrückt".
    Der Fehler kommt zwar, aber das "Prog" stürzt eben nicht so ab wie in der Studio-Ausführung.
    Das hat mich einiges gelehrt.
    • Code immer prüfen
    • So wenig wie möglich Try Catch
    • Code wieder prüfen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    So wenig wie möglich Try Catch


    Dazu fange nur die Exceptions ab, die du an dieser Stelle erwartest. Fängst du alle Exceptions ab, könnte eine dabei sein die unerwartet ist und keine Behandlung für implementiert wurde, was an andere Stellen zu Fehlern führen könnte.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    ErfinderDesRades schrieb:

    Man kann eine Methode schreiben, die die Daten holt und als Return-Value returnt.


    RISSN schrieb:

    im Moment führe ich nur diese Dinge in dem Button aus

    VB.NET-Quellcode

    1. Dim StartZeit As Date
    2. Dim StopZeit As Date
    3. Dim Dialog As New frmDialog
    4. Try
    5. Dialog.Show()
    6. Cursor.Current = Cursors.WaitCursor
    7. StartZeit = DateTime.Now
    8. Dialog.Refresh()
    9. Me.GetObjects.ObjectLog.Clear()
    10. DGV.Refresh()
    11. Info.Text = "=== Lese Daten aus der Datenbank ==="
    12. Status.Refresh()
    13. Me.ObjectLogTableAdapter.Fill(Me.GetObjects.ObjectLog, TagList.Text, txtStartTime.Text, txtStopTime.Text)
    14. DATAGRIDVIEW_Sort(DGV)
    15. lblRowInfo.Text = "Es wurden " & DGV.Rows.Count & " Einträge gefunden"
    16. Catch ex As System.Exception
    17. RJMessageBox.Show(ex.Message, "Fehler in Anwendung", MessageBoxButtons.OK, MessageBoxIcon.Error)
    18. Info.Text = "=== ein Fehler ist aufgetreten beim lesen der Daten ==="
    19. Status.Refresh()
    20. End Try
    Na, das ist ja keine Methode. Das sind Zeilen, die in einer Methode stehen, vermutlich.

    Und nochmal die Anforderung: "Man kann eine Methode schreiben, die die Daten holt und als Return-Value returnt."
    Deine Zeilen machen aber alles durcheinander: DataTable befüllen, Controls leeren, Controls betexten.
    Und returnen tun sie schoma garnix - sind ja auch nur lose Zeilen - keine Methode.

    Mit "Methode schreiben, die die Daten holt und als Return-Value returnt" ist aber eine Methode gemeint, die die Daten holt und als Return-Value returnt.
    Ganz genau das.
    Und sonst darf sie nichts tun. (weil alles andere wären - bei Verlegung nach Async - ungültige threadübergreifende Zugriffe).
    Kriegste das hin?
    bisher brauchte es noch keine Methode, deswegen ist der kleine Code nur im Button Click Ereignis (es holte die Daten ja per Binding). Starten kann ich das auch im externen Thread, einfach mit Await und den Button natürlich Async. Der Fehler ist dann weg, wenn ich ...

    VB.NET-Quellcode

    1. Me.ObjectLogTableAdapter.Fill(Me.GetObjects.ObjectLog, TagList.Text, txtStartTime.Text, txtStopTime.Text)


    hier nicht auf die Objekte des Hauptformulars zugreife. Wenn ich die vorher auf eine Variable schreibe, dann komm kein Fehler, aber in der Entwicklung kommen dann keine Daten, bin ich nicht in der Entwicklung, dann kommen Daten, etwas merkwürdig. Ich habe das gleiche so im Chart gemacht, da geht es und vor allem auch deutlich schneller wenn es asynchron ausführt.

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

    ich habe natürlich den Code noch nicht geändert, außer die Parameters sind jetzt keine mehr, die sich auf die Hauptform beziehen. Natürlich habe ich diverse Methoden (Funktionen) ob mit oder ohne Rückgabe, aber ich habe ein gebundenes Gridview und daher dachte ich, es macht keinen Sinn, es in eine Funktion zu packen, was soll ich denn zurück geben? Das wäre doch ein Schritt und/oder Variable mehr, oder nicht? Ich weiß, du hast mir schon einmal sehr geholfen und du weißt warum? Lass es mich wissen. Vor allem wie ich die Funktion erstellen soll? Der Aufruf packt die Daten ja gleich ins Gridview und wie kann ich eine Funktion erstellen dafür? Ich lerne sehr gerne dazu, dass ist wirklich so und ich bin dankbar für jegliche Hilfe.
    Ich glaube die Fill Methode wird dem Thread gar nicht übergriffig, sondern es sind die BindingSources und DataGridViews, die dran nuckeln.
    Weißt du wie man die ordentlich abstöpselt?

    Die Fehlermeldung kommt womöglich gar nicht aus der Fill-Methode. Deswegen siehst du auch keinen Fehler außerhalb des Studios, weil das alles im Nebenthread auf die Schnauze fliegt, die Fill aber ordentlich ihre Daten abliefert.
    Hatte ich auch neulich hier. Bis Post 7 relevant. Geht da am Ende um nen Spezialfall davon, aber es werden auch die Standardszenarien angesprochen.

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

    Sorry für die späte Antwort. Mehr als oben im Code zu sehen ist, mache ich nicht. Alles andere machen die Objekte ja selbst. Am Anfang habe ich gedacht, es ist besser, aber heute würde ich fast darauf verzichten und die Zellen selbst füllen, macht mehr Arbeit aber man hat auch mehr Freiraum. Aber oben ist der Code, mehr gibt es nicht, deswegen kann ich nichts posten.
    Das is natürlich Quatsch, weil wenn du den Code oben so einfügst, wie er is, kompiliert das Studio nich. Da fehlt halt der Methoden- und der Klassenrumpf.

    Davon abgeshen hab ich dir ja gesagt, ist der richtige Umgang mit den Objekten, die durch Designer-Code arbeiten, ebenso relevant.

    RISSN schrieb:

    Alles andere machen die Objekte ja selbst
    Eine BindingSource stöpselt sich z.B. eben nicht von selbst ab.