Entwickler-Ecke
WinForms - Windows Forms Timer Problem
daeve - So 26.06.11 20:57
Titel: Windows Forms Timer Problem
Hallo zusammen
Ich programmierte mir einen Countdown Timer, das ding läuft auch bis auf die Fehler...
Das Problem ist:
Wenn ich den Timer starte läuft er bis null und spielt seinen Sound, aber wenn ich jetzt den Timer nochmals starte zählt er in 2 -3 sekunden abständen pro sekunde herunter.
Und das ich den Timer mit [timer.stop();] nicht anhalten kann und wider starten ist mir auch ein Rätsel..
denn ich möchte auch eine Pause/Weiter funktion haben.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| public void timerStart(int time) { TimeSpan ts = TimeSpan.FromMilliseconds(time); countdownTimer = ts; countdownTime = countdownTimer.ToString();
timer.Interval = 1000; timer.Tick += new EventHandler(t1_Tick); timer.Start(); }
void t1_Tick(object sender, EventArgs e) { int i = Convert.ToInt32(countdownTimer.TotalMilliseconds); if (i <= 0) { timer.Stop(); } TimeSpan ts = TimeSpan.FromMilliseconds(i - 1000); countdownTimer = ts; countdownTime = countdownTimer.ToString(); if (countdownTimer.TotalMilliseconds == 0) { startSound(); } } |
norman2306 - Mo 27.06.11 11:43
Du darst den Timer nur einmal initialisieren. Sonst hast du mehrere Instanzen, die deinen Timer runterzählen. Außerdem ist der Timer nicht exakt, also solltest du es vermeiden, den Timer alle x-Sekunden aufzurufen und darauf hoffen, dass er auch wirklich exakt alle 1000ms aufgrufen wird. Mit der Zeit können sich da ein paar Fehler aufsummieren.
Ich würde es daher etwas anders angehen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| Stopwatch countdownTimer = new StopWatch(); int countdownTime = 0; BackgroundWorker worker = new Backgroundworker();
public MyStopwatch() { worker.DoWork +=new System.ComponentModel.DoWorkEventHandler(DoWork); }
public void Start() { countdownTime = 10000; countdownTimer.Start(); backgroundWorker1.RunWorkerAsync(); }
public void Pause() { countdownTimer.Stop(); }
public void Reset() { countdownTimer.Reset(); backgroundWorker1.CancelAsync(); }
void DoWork(object sender, DoWorkEventArgs e) { var left = ountdownTime - countdownTimer.ElapsedMiliseconds;
while(left > 0) { if (worker.CancellationPending == true) { e.Cancel = true; return; } left = countdownTime - countdownTimer.ElapsedMiliseconds; if(left > 20) { Thread.Sleep(left > 1000 ? 1000 : left - 20); } } DoWorkOrRaiseEventOrDoAnything(); countdownTimer.Reset(); } |
daeve - Mo 27.06.11 12:10
norman2306 hat folgendes geschrieben : |
Du darst den Timer nur einmal initialisieren. Sonst hast du mehrere Instanzen, die deinen Timer runterzählen. Außerdem ist der Timer nicht exakt, also solltest du es vermeiden, den Timer alle x-Sekunden aufzurufen und darauf hoffen, dass er auch wirklich exakt alle 1000ms aufgrufen wird. Mit der Zeit können sich da ein paar Fehler aufsummieren.
Ich würde es daher etwas anders angehen:
|
Das dachte ich mir auch, aber wenn der Timer "static" ist dürfte das ja nicht mehr passieren.
Ich schaue mir mal dein B.s an, danke dir !
norman2306 - Mo 27.06.11 13:21
Das hat mit static nichts zu tun. Auch ein als static deklariertes Feld beinhaltet eine Instanz eines Timers. Wenn du dem Feld einen neuen Wert zuweist, änderst du nur erstmal nur den Typ-Instanz-unabhängigen Verweis, der Timer bleibt aber erhalten, bis er vom GC entfernt wird. Static bedeutet nicht, dass es plötzlich nur noch eine Instanz des Typen geben kann, sondern das deine Klasse nur eine (objektunabhängige) Instanz verwaltet.
daeve - Mo 27.06.11 14:14
norman2306 hat folgendes geschrieben : |
| Das hat mit static nichts zu tun. Auch ein als static deklariertes Feld beinhaltet eine Instanz eines Timers. Wenn du dem Feld einen neuen Wert zuweist, änderst du nur erstmal nur den Typ-Instanz-unabhängigen Verweis, der Timer bleibt aber erhalten, bis er vom GC entfernt wird. Static bedeutet nicht, dass es plötzlich nur noch eine Instanz des Typen geben kann, sondern das deine Klasse nur eine (objektunabhängige) Instanz verwaltet. |
Okey, das habe ich vertanden thx :)
habe das problem gelöst...ich darf den Interval nicht neu setzen, warum auch immer...
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| public void timerStart(int time) { TimeSpan ts = TimeSpan.FromMilliseconds(time); countdownTimer = ts; countdownTime = countdownTimer.ToString();
if (timer.Interval == 1000) { timer.Start(); } else { timer.Interval = 1000; timer.Tick += new EventHandler(t1_Tick); timer.Start(); } } |
bakachan - Mo 27.06.11 14:21
Ich glaube nicht das es mit dem Intervall zusammenhängt sondern eher mit dem Eventhandler (du hängst ja immer einen Handler mehr an ohne den alten zu lösen)
norman2306 - Mo 27.06.11 16:11
jop, da hat bakachan recht.
daeve - Mi 06.07.11 23:42
ja, das Problem war der neue eventhandler. thx
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!