Alternative zu Thread.Sleep(x);



  • [Win Forms:]
    Hi!
    Ich würde gerne eine einfache Verzögerung in mein Programm einbauen, aber musste mich schon mehrfach davon überzeugen, dass Thread.Sleep() totaler müss für meine Zwecke ist.. Ein Beispiel:

    label1.Text = "Anfang...";
    System.Threading.Thread.Sleep(5000);
    label1.Text = "5 Sekunden später";
    

    Hat das Ergebis, dass 5 Sekunden lang nichts passiert und dannach der Text (wahrscheinlich) so kurz auf 'Anfang...' steht, dass man es nicht sieht und direkt dannach auf '5 Sekunden später' umspringt.

    Was mach ich falsch und gibt es irgend eine brauchbare Alternative??

    🙂 Darius###



  • Wenn du label1.Text = "..."; setzt, dann wird an der Stelle nur der neue Text in die zuständige Variable des Controls übernommen, und vermerkt dass das Control neu gezeichnet werden muss (bzw. dass der Bereich des Fensters wo das Control liegt neu gezeichnet werden muss). Das eigentliche Zeichnen wird hier aber noch nicht gemacht.

    Das passiert erst, nachdem deine Handler-Funktion fertig gelaufen ist. Dann läuft das Programm wieder in den Message-Loop. Mal abgesehen davon wie das passiert bekommt das Programm an dieser Stelle dann mit dass es etwas gibt was neu gezeichnet werden muss, und sorgt dafür dass das dann auch passiert.

    Es gibt jetzt grundsätzlich zwei Möglichkeiten damit umzugehen:

    1. Nach dem Ändern des Text label1.Update(); aufrufen. Das bewirkt dass das Control sofort neu gezeichnet wird. Nachteil: das darauf folgende Sleep blockiert trotzdem das ganze Fenster, der User kann in der Zeit *nichts* mit dem Fenster machen - keine Buttons klicken, kein Menu aufmachen, nichts. Je nach Windows-Version und Desktop-Composition Modus "verschwindet" in dieser Zeit auch der ganze Inhalt des Fensters, wenn man z.B. ein anderes Fenster davor "vorbeizieht". Weil dein Handler eben noch nicht fertig gelaufen ist, und daher der (für das Neu-Zeichnen des Fensters zuständige) Message-Loop nicht läuft.

    2. Du setzt die Pause mit etwas anderem als Thread.Sleep um. Beispielsweise kannst einen Timer starten, der dann eine 2. Funktion aufruft, in der der 2. Teil des Handler-Codes steht. Nachteil: schwieriger umzusetzen. In der Zeit bis der Timer triggert kann der User das Fenster ganz normal verwenden, also auch auf Buttons klicken etc. was den Aufruf weiterer Handler zur Folge hat. Damit das Programm keinen Unsinn baut, ist es dann oft nötig während dieser Zeit z.B. alle Buttons zu disablen.



  • Ich denke ich nehme einfach das erste...
    Das wusste ich nicht 😃 Aber ich war noch nie so zufrieden mit einer Antwort, die ich hier bekommen hab wie mit deiner grade 🙂

    Ich hatte auch an einen Timer gedacht, aber iwie find ich das unschön, da ein Timer ja für das Regelmäßige Aufrufen einer Funktion in einem bestimmten Intervall und nicht für eine einmalige Verzögerung gedacht ist..

    Liebe Grüße,

    Darius



  • #Darius# schrieb:

    Ich hatte auch an einen Timer gedacht, aber iwie find ich das unschön, da ein Timer ja für das Regelmäßige Aufrufen einer Funktion in einem bestimmten Intervall und nicht für eine einmalige Verzögerung gedacht ist..

    3.Alternative: Erstelle einen Thread in dem du Thread.sleep aufrufst und danach über label1.Invoke(() => {label1.Text = "5 Sekunden später"}); (das ist aber etwas komplizierter aber schöner: http://msdn.microsoft.com/de-de/library/zyzhdc6b(v=vs.80).aspx

    Edit:



  • Ja, mit einem Worker-Thread kann man das ganze etwas "übersichtlicher" lösen. Und vor allem funktioniert die Thread-Variante nicht nur für dumme "Sleeps", sondern auch wenn mal die eigentliche Arbeit die da gemacht wird etwas länger dauert.

    Wobei auch hier der Dialog bzw. zumindest bestimmte Controls disabled werden sollte während der Thread läuft.
    Sonst hat man das selbe Problem wie mit dem Timer.



  • Mir fallen da noch das gute alte "Application.DoEvents()" ein oder "Form.Refresh()" bzw. "Control.Refresh()" um u.a. ein Neuzeichnen zu erzwingen.



  • Thx.. Euch...

    Andere Frage...

    Ist nicht sonderlich wichtig, deshalb will ich keinen neuen Thread machen:

    Wie kann man die Marque-Animation einer ProgressBar (WinForms) anhalten/pausieren??

    Sharpige 🙂 Grüße, Darius...
    PS: ^^>>Lustiges Wort 😃





  • hustbaer schrieb:

    Hilft dir das?
    http://stackoverflow.com/questions/312936/windows-forms-progressbar-easiest-way-to-start-stop-marquee

    Oh ja.. 🙂

    Ich hatte mir schon mit einer etwas 😉 unstylischen Methode aushelfen lassen müssen. Welche das war, sag ich besser nicht 🙂

    Lg Darius



  • Lass mich raten...
    Zwei Controls an der selben Position, ein Progress-Bar und ein Static-Image-Control, und dann jeweils immer nur eins sichtbar machen?


Anmelden zum Antworten