Wie macht man eine Endlose (dauerhafte) Datenbankabfrage die immer wieder nach neuen Zeilen guckt?

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von EaranMaleasi.

    Wie macht man eine Endlose (dauerhafte) Datenbankabfrage die immer wieder nach neuen Zeilen guckt?

    Hallo Ihr VB-Experten.
    Ich arbeite immoment an einer Konsolenanwendung und hoffe hier auf Hilfe da ich etwas realisieren muss ohne große Ahnung von VB zu haben.

    Zur Aufgabe:
    Ich habe eine Datenbank mit der Tabelle Scanfiles.
    Diese Tabelle aktualisiert sich ständig und dauerhaft (teilweise mehrfach pro Sekunde) und es werden immer wieder neue Zeilen angelegt von verschiedenen Clients.

    Für den Server brauche ich nun eine Konsolenanwendung die in einer Endlosschleife immer wieder diese Tabelle abfragt und neue Zeilen einmalig ausliest, verarbeitet und löscht. Leider habe ich keine Idee wie ich dass realisieren kann, egal was ich versuche hat es entweder zur Folge dass die Anwendung seitens VB beendet wird

    Ich habe bisher mehrere Dinge versucht aber alles ist irgendwie zum Scheitern verurteilt.

    Unten angehängt einmal der Anfang des Sub dass ich geschrieben habe:

    Ich habe bisher 4 Sachen versucht aber alles ohne Erfolg:

    Versuch 1:
    Ich habe dass Sub Recursiv aufgerufen (so wie es hier unten noch zu sehen ist) - also ein Selbstaufruf am Ende - was dazu führt dass eine StackOverflow-Exception erzeugt wird.

    Versuch 2: Ich habe via While(true) dass ganze Sub in sich endlos laufen lassen (ihr seht es unten auskommentiert) was zu funktionieren scheint aber dass führt dazu dass ich im Taskmanager sehe dass sich der Prozess immer weiter und weiter aufbläht und dieser immer und immer mehr speicher an sich reißt.

    Versuch 3: Ich habe die SQL-Verbindung getrennt und neu aufgebaut vor jedem Aufruf in der Hoffnung dass er dann reservierte/genutzte Resourcen freigibt, leider ändert dass garnichts an Versuch Nummer 2.

    Versuch 4: Ich habe die Konsole immer wieder per Clear geleert so dass nur der aktuelle Durchlauf ausgegeben ist - leider ändert auch dass nichts daran dass der Prozess sich wie in Versuch 3 weiter und weiter aufbläht.

    Ich hoffe nun hier einige gute Tipps zu bekommen wie ich es hinbekomme dass ich dass Sub endlos immer und immer wieder von vorne arbeiten lassen kann sobald es fertig ist.

    Visualisierte Grüße aus RheinlandPfalz

    janben

    Ps: Erstmal will ich zum testen nur ne Consolenausgabe haben, wenn die einwandfrei läuft soll eigentlich nichts weiter gemacht werden als die Datenbankzeile zu löschen und 3 Werte des Row an eine Kommandozeilenanwendung zu übergeben.

    Sub doProcessing()
    ' While (True)
    'MySqlConnection.Close()
    'MySqlConnection.Open()
    Console.Clear()
    Dim stm As String = "SELECT `id`,`prozessid`,`filename`,`zeit`,"
    stm = stm & " (SELECT `sourcefolder` FROM `scanprozesse` WHERE `scanprozesse`.`id` = `scanfiles`.`prozessid`), "
    stm = stm & " (SELECT `destinationfolder` FROM `scanprozesse` WHERE `scanprozesse`.`id` = `scanfiles`.`prozessid`) "
    stm = stm & " FROM `scanfiles` WHERE `zeit` < date_sub(now(), interval 20 Second)"
    Dim cmd As MySqlCommand = New MySqlCommand(stm, MySqlConnection)
    Dim reader As MySqlDataReader = cmd.ExecuteReader()
    While reader.Read()
    Console.WriteLine(reader.GetInt32(0) & ": " & reader.GetString(5))
    End While
    cmd.Dispose()
    reader.Close()
    ' End While

    Console.WriteLine("Durchlauf beendet")
    doProcessing()

    'Console.ReadLine()

    End Sub



    EDIT: Es hat sich erledigt. Habe es jetzt hinbekommen mit einer While-Endlosschleife. Hatte nur vergessen reader.close() anzuwenden...

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

    Sowas nennt man Pollen, und man ist meist nicht sehr glücklich damit, weil solch eine kontinuirlich hohe Prozessorlast erzeugt, die "im Ruhezustand" unverändert ist, ohne irgendetwas wirklich zu tun.

    Und eine Endlos-Schleife ist die schlimmste Art des Pollens, damit belegst du möglicherweise einen Cpu-Kernel mit Dauerlast 100% - also wenn's tatsächlich so ist, wird das ein erheblich beschleunigtes Altern hervorrufen, und auch den Kühler in pausenlosen Betrieb halten.

    Eine günstigere Art zu Pollen ist mit einem Timer. Überleg dir ein Interval, was du bereit bist zu akzeptieren, und mach deine Operationen mw. im Abstand von 300ms. Aber gerne auch im Sekundentakt, oder was spricht eiglich dagegen, wenns nur Minütlich ausgeführt wird?

    Ach Quatsch. Du kannst die Cpu in einer Consolen-Anwendung auch einfach mit System.Threading.Thread.CurrentThread.Sleep(3000) innerhalb der Endlos-Schleife für 3 Sekunden entlasten - ein Timer wäre viel mehr Aufwand.

    Beachte aber, dass das Proggie während des Sleepens eingefroren ist, und nur alle 3s ühaupt reagiert. Ansonsten muss halt doch ein Timer her, aber wie gesagt: Ist viel höherer Aufwand, das ergibt dann ja bereits eine MultiThreading-Anwendung.

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

    Minütlich ist viel zu selten.... Pro Minute werden fast 10.000 Zeilen angelegt....
    Und ne die Prozessorlast ist super, läuft Stabil und so wie es soll, habe aber bei dem anderen Script ein Problem - vielleicht kannst du mir ja da auch was zu sagen? Siehe meinen anderen Post...
    Wenn in einer Minute 10.000 Datensätze erzeugt werden, dann sind das pro Sekunde fast 1270 Datensätze.

    Bist du überhaupt in der Lage, diese 170 Datensätze in einer Sekunde zu verarbeiten ? Bedenke, es kommt Zeitaufwand fürs Abfragen und Löschen aus der DB dazu. Wenn nein, ist es völlig unwichtig, wie du die Daten abfragst und welche Methode dafür zum Einsatz kommt. Du wirst es nie schaffen, die Daten alle rechtzeitig zu verarbeiten und die DB wird unweigerlich vollaufen.

    Wenn es nicht nötig ist, das alles möglichst zeitnah durchzukauen, dann kannst du dir auch etwas Zeit lassen mit der Abfrage. Alle Minute mal 10k Datensätze durchzugehen ist vielleicht doch völlig ausreichend...