Autor Beitrag
daeve
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 116
Erhaltene Danke: 3

Windows (XP Pro, 7 Ultimate x64)
C#,WPF,Java,ASP.Net, VS 2010 Ultimate (x86)
BeitragVerfasst: So 26.06.11 20:57 
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.


ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: 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:

ausblenden volle Höhe 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 116
Erhaltene Danke: 3

Windows (XP Pro, 7 Ultimate x64)
C#,WPF,Java,ASP.Net, VS 2010 Ultimate (x86)
BeitragVerfasst: Mo 27.06.11 12:10 
user profile iconnorman2306 hat folgendes geschrieben Zum zitierten Posting springen:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 116
Erhaltene Danke: 3

Windows (XP Pro, 7 Ultimate x64)
C#,WPF,Java,ASP.Net, VS 2010 Ultimate (x86)
BeitragVerfasst: Mo 27.06.11 14:14 
user profile iconnorman2306 hat folgendes geschrieben Zum zitierten Posting springen:
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...

ausblenden 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// Intervall festlegen
                timer.Tick += new EventHandler(t1_Tick); // Eventhandler ezeugen der beim Timerablauf aufgerufen wird 
                timer.Start(); // Timer starten
            }
            
        }
bakachan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 503
Erhaltene Danke: 34

W7 (x64) Ultimate
C# / VB.NET (VS2010 Ultimate)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Mo 27.06.11 16:11 
jop, da hat bakachan recht.
daeve Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 116
Erhaltene Danke: 3

Windows (XP Pro, 7 Ultimate x64)
C#,WPF,Java,ASP.Net, VS 2010 Ultimate (x86)
BeitragVerfasst: Mi 06.07.11 23:42 
ja, das Problem war der neue eventhandler. thx
ujr
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 102
Erhaltene Danke: 12



BeitragVerfasst: Do 07.07.11 10:46 
Wie nett, diese Frage trotz Antworten hier auch noch woanders zu posten:
www.mycsharp.de/wbb2...d.php?threadid=96545