Warte / Wait / Sleep / DoEvents Funktion zum Anhalten des Programmes für eine bestimmte Zeit

  • VB.NET

Es gibt 37 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    Warte / Wait / Sleep / DoEvents Funktion zum Anhalten des Programmes für eine bestimmte Zeit

    Hallo Leute!

    Um dem Anwender etwas Zeit zu geben Anzeigen am Bildschirm auch lesen zu können, habe ich mir in VB6.0 eine kleine Warte-Funktion geschrieben. Ich dachte in VB2012 gäbe es sowas bereits, aber weit gefehlt. Konnte nichts finden.

    Daher habe ich die Wartefunktion für VB2012 adaptiert.

    Übergeben wird als Parameter lediglich die Anzahl der Sekunden die gewartet werden soll:

    VB.NET-Quellcode

    1. Private Sub warte(Sekunden As Double)
    2. Dim ZeitSpanne As Double
    3. Dim Start As Double
    4. ZeitSpanne = Sekunden / 100000
    5. start = DateTime.Now.ToOADate() ' Anfangszeit setzen.
    6. Do While DateTime.Now.ToOADate() < Start + ZeitSpanne
    7. Application.DoEvents() ' Steuerung an andere Prozesse abgeben
    8. Loop
    9. End Sub


    Der Aufruf ist sehr simpel:

    VB.NET-Quellcode

    1. frm_about.Show()
    2. frm_about.Label2.Text = "Lade benötigte Daten in den Speicher .."
    3. warte(2) '2 Sekunden warten
    4. frm_about.Label2.Text = "System wird gestartet .."
    5. warte(0.5) 'eine halbe Sekunde Warten
    6. frm_about.Close()


    Durch das Application.DoEvents() wird der Prozess auch nicht eingefroren.

    LG Roland
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Meinst du so was?

    VB.NET-Quellcode

    1. System.Threading.Thread.Sleep(100000)
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."

    dive26 schrieb:

    Um dem Anwender etwas Zeit zu geben Anzeigen am Bildschirm auch lesen zu können,

    Die frage ist, ob diese Anzeigen überhaupt nötig sind, wenn das System sowieso schneller arbeitet, als dass man das ganze Lesen könnte. Ist zwar nett, dass man dem Anwender was zu Lesen gibt, aber dafür Zeit verschwenden? jeder Anwender ist doch froh darüber wenn das Programm ruckzuck da ist.
    System.Threading.Thread.Sleep(100000)
    Ist unbrauchbar, da friert das ganze Programm ein.


    Ist zwar nett, dass man dem Anwender was zu Lesen gibt, aber dafür Zeit
    verschwenden? jeder Anwender ist doch froh darüber wenn das Programm
    ruckzuck da ist.
    Im Grunde genommen hast Du natürlich recht, trotzdem gibt es Anforderungen wo dies notwendig ist. Das gepostete Beispiel ist natürlich nur ein Beispiel.

    LG Roland
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    Ist unbrauchbar, da friert das ganze Programm ein.
    Eben deswegen nimmt man ja Timer oder Threads.
    Da du aus VB6 kommst, kannst du das vermutlich nicht wissen, deswegen will ich dir hier auch nichts vorwerfen, aber: Application.DoEvents ist in .Net ein NoGo.
    Ok, hast Du zufällig ein CodeSchnippsel für mich, wie so was mit Threads oder Timer geht?
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Timer ist ganz einfach. Du ziehst dir nen Timer aus der Toolbox und stellst dann die gewünschte Anzahl Millisekunden ein. Dann startest du den Timer (geht von über all aus dem Code) mit Timer.Start() bzw. Timer Enabled = True (letzteres kannst du auch direkt im Designer einstellen, sodass der Timer gleich von Beginn an läuft). Der Timer wird dann in den von dir eingestellten Intervallen das Tick-Event auslösen.
    Das ist die einzige Umstellung, also von Sequentiell nach Eventbasiert, aber so funktionieren moderne Sprachen nunmal. Vorteil ist, dass du zwischen dem Starten des Timers und dem Tick-Event auch irgend was anderes machen kannst, da du den Thread ja nicht mehr mit ner Do-Schleife beanspruchst.
    Das solltest du beherzigen, wenn du ganz neu von der VB6 Ecke kommst...
    böse Funktionen vermeiden
    da läufst du gar nicht erst in Gefahr, mit diesen Funktionen zu programmieren...

    schaue dir das einmal genau an Timer (MSDN)

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

    Artentus schrieb:

    Das ist die einzige Umstellung, also von Sequentiell nach Eventbasiert, aber so funktionieren moderne Sprachen nunmal. Vorteil ist, dass du zwischen dem Starten des Timers und dem Tick-Event auch irgend was anderes machen kannst, da du den Thread ja nicht mehr mit ner Do-Schleife beanspruchst

    Während dieser "Waits" möchte ich generell nichts ausführen. Das steht auf jeden Fall mal fest. Überall dort wo ich währenddessen was anders ausführen möchte, dass eine bestimmte Zeit braucht, brauche ich das wait auch nicht.

    Der Programmcode muss aber (bei 170.000 Zeilen) so überschaubar sein, dass ich nur eine Zeile für die Wartefunktion brauche.

    Also müsste ich diese Timer-Funktion irgendwie in eine SUB / END SUB Prozedur bekommen, die ich wie gewohnt mit warte (x) aufrufen kann.

    Da muss ich noch etwas tüfteln wie ich das hinbekomme. Das Problem: Timer benötigt immer eine Form (oder?). Wenn ich aus bestimten Gründen (bitte nicht hinterfragen warum und wozu) in einem Modul eine Wartepause einlegen möchte, brauch ich immer zugriff auf eine Form.

    LG Roland

    PS: Genau das ist ein Punkt den ich nicht verstehe. Da schreibt MS eine neue Progammiersprache und baut nicht mal eine richtige Sleep-Funktion ein ...
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Es geht nur über Events, das lässt sich nicht in eine Sub packen, ansonsten würdest du wieder mit DoEvents warten. DoEvents ist vergleichbar, wie wenn du neben deinem Braten am Ofen stehst und nur auf die Uhr schaust, Events dagegen sind, dass du dir nen Wecker stellst und so lange was anderes machst (kann auch faulenzen sein), bis dieser klingelt.

    Wenn du Probleme damit hast, dich in deinem Programm zurechzufinden, weil zu viel Code auf einem Haufen ist, dann solltest du dringend darüber nachdenken, es besser zu strukturieren (heißt Code in Klassen usw. auslagern).

    dive26 schrieb:

    Da schreibt MS eine neue Progammiersprache und baut nicht mal eine richtige Sleep-Funktion ein
    Tja - Umdenken ist die Devise.
    Und diese Devise wird dir noch so einige Male begegnen (und meist erscheint sie als Wand, wo man dagegen-läuft).

    In .Net-Programmen wird nicht gewartet oder geschlafen - punktum.

    Stattdessen mags Ereignisse geben, wie zB. Timer-Tick: Zu einem Zeitpunkt mag sich ereignen, dass etwas auftaucht, und zu einem anneren Zeitpunkt, dasses wieder verschwindet.

    dieses Buch lesen (hingegen das Galileio-Openbook ist Mist) - enthält auch ein Kapitel für vb6-Umsteiger (habs nicht gelesen, aber ist das einzige mir bekannte Buch, was dieses brennende Problem problematisiert).

    nafets3646 schrieb:

    Mach dir doch am besten erstmal ein paar Klassen, das ist das beste für die Übersichtlichkeit.

    So weit bin ich noch gar nicht. Ich bin immer noch bei den Grundlagen. Das einzige was ich jetzt erst mal machen möchte ist:

    1. Programm über ein Modul starten (nicht über eine Form) = funktioniert
    2. Eine Form öffnen = funktioniert
    3. Eine vordefinierte Zeitspanne warten = in Arbeit ?(
    4. Die Form wieder schließen = funktioniert

    Dazu brauche ich noch keine Klasse (zumindest wüsste ich nicht was ich davon dort reinpacken sollte).

    Da ich (wie die meisten VB6 Flüchtlinge) eher was mit Modulen anzufangen weis als mit Klassen, wird das noch ein langer Lernprozess. Soweit ich das verstanden habe sind Klassen eigentlich nur "leere"
    Grundgerüste von Aufgaben und Parametern die ich normalerweise in Module packe
    (laienhaft ausgedrückt). Ich wüsste zur Zeit noch nicht, was ich von meinem zukünftigen Codes sinnvollerweise in eine Klasse packen sollte. Irgendwann macht es aber sicher auch bei mir Klick und ich weis es ;)

    Wenn du Probleme damit hast, dich in deinem Programm zurechzufinden,
    weil zu viel Code auf einem Haufen ist, dann solltest du dringend
    darüber nachdenken, es besser zu strukturieren (heißt Code in Klassen
    usw. auslagern).
    Diese "Warte"-Routine liegt derzeit in einem separaten Modul - zwecks Übersichtlichkeit. Welchen Vorteil hätte ich diesen Code in eine Klasse zu packen, außer dass ich zur Verwendung der Klasse diese zuerst instanzieren müsste?

    Stattdessen mags Ereignisse geben, wie zB. Timer-Tick: Zu einem
    Zeitpunkt mag sich ereignen, dass etwas auftaucht, und zu einem anneren
    Zeitpunkt, dasses wieder verschwindet.
    Das hört sich ja theoretisch gut und vernünftig an, aber in der Praxis kann ich damit nicht wirklich etwas anfangen. Nehmen wir an ich bin ein Programm und arbeite ununterbrochen. Sobald ich was erledigt habe gehe ich die nächste Aufgabe auf der Liste an.

    Kommt jetzt die Anweisung "Mach mal 5 Minuten Pause bis Dich der Wecker aufweckt (Timer)", dann geht das nicht, weil ich nicht weis was ich in den 5 Minuten bis dorthin anfangen soll (ich schlafe ja nicht) und ich immer stur meiner Aufgabenliste nachgehe. Ich müsste mich also 5 Minuten lange mit einer Arbeit beschäftigen "Warte (300)" oder ich gehe gleich die nächste Aufgabe in der Liste an.

    Ich hoffe ich konnte mein Problem anschaulich erklären.
    Wenn ich mich auf einer Form befinde und auf Benutzereingaben reagiere, dann ist es ja kein Problem mit dem Timer-Event irgendwann was auszugeben. Aber in einem Modul das schrittweise abgearbeitet wird kann ich ja nicht so einfach auf einen Timer warten.

    LG Roland
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    Diese "Warte"-Routine liegt derzeit in einem separaten Modul - zwecks Übersichtlichkeit. Welchen Vorteil hätte ich diesen Code in eine Klasse zu packen, außer dass ich zur Verwendung der Klasse diese zuerst instanzieren müsste?
    Das bezog ich auf die Aussage, dass du 170.000 Zeilen Code in deinem Programm hast, und es deswegen unübersichtlich sei.
    Da du das aber offensichtlich nicht hast, sollte es auch keine Übersichtlichkeitsprobleme durch Events geben. Übrigens gibt es auch Timer, die keine Form (also eigentlich braucht der normale Timer auch keine Form, sondern nen MessageLoop) brauchen, z.B. der System.Timers.Timer. Da musst du allerdings aufpassen, denn der läuft in nem anderen Thread.

    Nehmen wir an ich bin ein Programm und arbeite ununterbrochen. Sobald ich was erledigt habe gehe ich die nächste Aufgabe auf der Liste an.
    So funktioniert ein sequentielles Programm. VB.Net ist aber Eventbasiert, heißt, es wird nur was gemacht, wenn das Programm in irgend ner Weise einen Anstoß dafür bekommen hat. Und ja, das führt dann dazu, dass eine normale WinForms-Anwendung die meiste Zeit nichts tut, aber in ner eventbasierten Sprache ist das kein Widerspruch.
    Klar kann man in VB.Net auch sequenziell arbeiten, wenn man denn möchte, aber das ist 1. nicht so schön, da von der Sprache nur in maßen beabsichtigt und 2. auch komplizierter.

    dive26 schrieb:

    Kommt jetzt die Anweisung "Mach mal 5 Minuten Pause bis Dich der Wecker aufweckt (Timer)", dann geht das nicht, weil ich nicht weis was ich in den 5 Minuten bis dorthin anfangen soll (ich schlafe ja nicht) und ich immer stur meiner Aufgabenliste nachgehe. Ich müsste mich also 5 Minuten lange mit einer Arbeit beschäftigen "Warte (300)" oder ich gehe gleich die nächste Aufgabe in der Liste an.
    Richtiger Einwand.
    Die Lösung besteht darin, dasses eben doch einen Ort gibt, wo gewartet wird - nämlich den MessageLoop der Application. Nur dort wird gewartet - nirgends sonst. Und auch auf das Timer-Tick-Event wird dort gewartet.
    Aber dassis ziemlich tief inne Architektur von WinForms-Anwendungen.

    Vlt. hilft dir Alles über Events - da wird das auch eingangs thematisiert.

    dive26 schrieb:

    Diese "Warte"-Routine liegt derzeit in einem separaten Modul - zwecks Übersichtlichkeit. Welchen Vorteil hätte ich diesen Code in eine Klasse zu packen, ...?
    Keinen.
    IN einer Klasse wäre das ebenso schlecht oder noch schlechter als in einem Modul.
    Du kannst auch den Hauptthread schlafen legen. Nur macht das bei Benutzern keinen guten Eindruck, wenn "Keine Rückmeldung" auf dem Bildschirm erscheint.

    ErfinderDesRades schrieb:

    In .Net-Programmen wird nicht gewartet oder geschlafen - punktum.
    Da hast du vollkommen recht. Und das ist wie der TE schon gemerkt hat ein recht krasses umdenken. In .NET wirst du dich daran gewöhnen müssen, dass sehr viele Abläufe parallel ablaufen. Mit Einführung von .NET 4.5 wurde dies sogar noch auf ein noch höheres Level gebracht. Du musst dort nicht mal mehr mit Threads direkt arbeiten sondern die Runtime nimmt dir da recht viel ab. Dafür wurden extra zwei neue Schlüsselwörter eingeführt(async und await). Diese sind vorallem dafür da, dass sehr einfach, schnell und vor allem übersichtlich Operationen in neue Threads ausgelagert werden können. Dadurch soll eine flüssige und Anwenderfreundliche GUI gewährleistet werden. Aber auch in .NET 2.0,... gibt es Threads welche es einem recht leicht machen auf Operationen parallel ablaufen zu lassen. Wenn du GUIs mit Threads kombinierst, musst du aber darauf achten, dass du von einem neuen Thread nicht direkt auf GUI Elemente des Hauptthreads zugreifen kannst. Hierfür musst du die GUI invoken um z.B. Fortschrittsanzeigen zu aktualisieren. Als Resultat wird der Hauptthread nur mit der Aktualisierung eines Balken etc. belastet und der Rest läuft auf anderen Threads.

    Ich würde mir als Neueinsteiger allgemein erstmal Threads sehr gründlich durchlesen. Auf Channel9 gibt es auch tolle Videos zu Async/Await.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Danke, aber ich glaube Ihr habt meine Aufgabenstellung noch immer nicht ganz verstanden bzw. habe ich es nicht gut erklärt.

    Der Ablauf über ein Startmodul sollte in etwas so ablaufen:

    1. Start über Einsprungspunkt "Main"
    2. Ausgabe in einem Statusfenster, was gerade geschieht (z.B. "Lade Stammdaten" oder "Nehme verbindung zum Internet-Server auf").
    3. Die in Punkt 2 angekündigte Aufgabe wird so rasch wie möglich erledigt.
    Dies kann entweder 10 Millisekunden oder 20 Sekunden dauern (je nach Verbindungsgeschwindigkeit oder Datenbankgröße).
    Wie lange ist nicht vorherzusehen.
    Wird nach Abschluss der Funktion festgestellt, dass die Anzeigedauer unterhalb der Erkennungsschwelle lag, dann wird mit warte (x)
    entsprechend noch ein wenig gewartet bis die nächste Anzeige gebracht wird.
    Dauert die Aufgabe ohnehin länger, dann ist die Warte(x) Anweisung nicht notwendig.

    Ich sehe hier keine Möglichkeit über Timer zu arbeiten.

    Ich hoffe ich konnte verständlich machen worum es mir geht.

    Ich möchte, dass der User zu jederzeit weis was das Programm gerade macht.
    Wenn das Fenster mit "Lade Stammdaten" nur kurz aufblitzt, dann hat das keinen Sinn.

    Dafür wurden extra zwei neue Schlüsselwörter eingeführt(async und await).
    Das habe ich mir schon mal angesehen - dafür habe ich auch schon Verwendungsideen im Hinterkopf :thumbsup: (eigene Fortschrittsbalken etc..)



    LG Roland
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at