Stopbyte

Should I Use Timer or Thread.Sleep in C#?

Hello!
I am looking for the best way to create small animations in a WinForms.

My C# Code:

#if !TIMER
        private void DemarrerAnimation()
        {
            this._anim = true;
 
            using (Graphics g = Graphics.FromImage(this._fond))
            {
                while (this._anim)
                {
                    this.Dessiner(g);
                    System.Threading.Thread.Sleep(this._duree);
                }
            }
        }
 
        private void ArreterAnimation()
        {
            this._anim = false;
        }
 
        private void Dessiner(Graphics g)
        {
            if (this._pos.X < 0 || this._pos.Y < 0 ||
                (this._pos.X + 1) * this._taille + this._marge * 2 >= this.pictureBox1.ClientSize.Width ||
                (this._pos.Y + 1) * this._taille + this._marge * 2 >= this.pictureBox1.ClientSize.Height)
            {
                this._anim = false;
                return;
            }
 
            g.Clear(Color.Transparent);
            g.FillEllipse(Brushes.Black,
                this._marge + this._pos.X * this._taille,
                this._marge + this._pos.Y * this._taille,
                this._taille, this._taille);
 
            this.pictureBox1.Refresh();
            Application.DoEvents();
 
            switch (this._sens)
            {
                case 'L': this._pos.X--; break;
                case 'R': this._pos.X++; break;
                case 'U': this._pos.Y--; break;
                case 'D': this._pos.Y++; break;
                default: break;
            }
        }
#endif
 
        private void timer1_Tick(object sender, EventArgs e)
        {
#if TIMER
            if (this._pos.X < 0 || this._pos.Y < 0 ||
                (this._pos.X + 1) * this._taille + this._marge * 2 >= this.pictureBox1.ClientSize.Width ||
                (this._pos.Y + 1) * this._taille + this._marge * 2 >= this.pictureBox1.ClientSize.Height)
            {
                this.timer1.Stop();
                return;
            }
 
            using (Graphics g = Graphics.FromImage(this._fond))
            {
                g.Clear(Color.Transparent);
                g.FillEllipse(Brushes.Black,
                    this._marge + this._pos.X * this._taille,
                    this._marge + this._pos.Y * this._taille,
                    this._taille, this._taille);
 
                this.pictureBox1.Refresh();
 
                switch (this._sens)
                {
                    case 'L': this._pos.X--; break;
                    case 'R': this._pos.X++; break;
                    case 'U': this._pos.Y--; break;
                    case 'D': this._pos.Y++; break;
                    default: break;
                }
            }
#endif

I made two versions you can see above. both work well. I do not know which version should be preferred. using the timer or loop with Thread.Sleep() ?

thank you for your comments/remarks on this code!

3 Likes

Using Thread.Sleep() will pause the current thread execution, Pausing the UI Main thread will cause for the App to freeze.

So better use a Timer.

2 Likes

Of course, using System.Threading.Thread.Sleep(SleepDurationInMilliSeconds) to animate an object is normally worse than using Timer, especially when you use only one process ( main process ) with one thread ( main thread ).

But, if you use multi-threading architecture, the Threading model can be better than Timer model, because even in the Timer model the main thread can get some troubles.

In my opinion, Java and WPF(Windows Presentation Framework) are using a multi-threading model to increase animation speed and user-input-sensitivity.

But the multi-threading is harder to implement than single-threading, so you should carefully consider which model to use.

Thank you for reading my answer. Any question? Please inform me.

3 Likes