HOWTO · Csharp

Comment créer une minuterie de retard en C#

Cet article présente la façon de créer un temporisateur de retard en C#. Il inclut quatre méthodes différentes : Thread.Sleep(), Task.Delay(), System.Timers.Timer et System.Threading.Timer.

Sur cette page

Pour ajouter un délai en C#, choisissez Thread.Sleep() pour bloquer le thread actuel, Task.Delay() pour attendre de manière asynchrone, ou une classe de minuteur pour planifier un rappel. Les exemples ci-dessous utilisent un intervalle de deux secondes et montrent comment chaque option se comporte. Ils n’ont pas été exécutés dans l’environnement d’exécution fourni, donc aucun résultat observé n’est affirmé.

Utiliser la méthode Thread.Sleep() pour créer un délai en C#

Thread.Sleep() met le thread actuel en pause pendant le nombre de millisecondes spécifié. Comme ce thread ne peut pas effectuer d’autre travail pendant l’attente, n’utilisez cette approche que lorsque le blocage est approprié, par exemple dans un court programme console synchrone.

Cet exemple complet affiche un message, attend deux secondes, puis affiche un autre message :

using System;
using System.Threading;

class DelayExample
{
    static void Main()
    {
        Console.WriteLine("The delay starts.");
        Thread.Sleep(2000);
        Console.WriteLine("The delay ends.");
    }
}

L’argument est en millisecondes, donc 2000 demande une attente de deux secondes. Le temps réellement écoulé peut varier selon la planification du système.

Utiliser la méthode Task.Delay() pour créer un délai en C#

Task.Delay() crée une tâche qui se termine après l’intervalle demandé. L’attendre avec await dans une méthode asynchrone permet à cette méthode de céder pendant l’attente, contrairement à Thread.Sleep(), qui occupe le thread actuel. Appelez la méthode asynchrone depuis le flux asynchrone existant de votre application.

Cet exemple complet conserve l’attente asynchrone dans une méthode séparée et utilise un point d’entrée synchrone pour l’appeler :

using System;
using System.Threading.Tasks;

class DelayExample
{
    static void Main()
    {
        RunAsync().GetAwaiter().GetResult();
    }

    static async Task RunAsync()
    {
        Console.WriteLine("Before the delay");
        await Task.Delay(2000);
        Console.WriteLine("After the delay");
    }
}

L’expression await reprend RunAsync une fois la tâche de délai terminée. Dans une application qui utilise déjà des méthodes asynchrones, attendez directement Task.Delay(2000) avec await au lieu de bloquer le point d’entrée pour attendre la tâche.

Utiliser la classe System.Timers.Timer pour créer un délai en C#

System.Timers.Timer déclenche un événement Elapsed après son Interval en millisecondes. Définissez AutoReset sur false pour un événement unique ; définissez-le sur true lorsque l’événement doit se répéter à l’intervalle. Le rappel est piloté par les événements, donc le démarrage d’un minuteur ne met pas en pause la ligne de code suivante.

Cet exemple complet attend l’événement unique avant que le programme console ne se termine :

using System;
using System.Threading;
using System.Timers;

class DelayExample
{
    static void Main()
    {
        using (var completed = new ManualResetEvent(false))
        using (var timer = new System.Timers.Timer(2000))
        {
            timer.AutoReset = false;
            timer.Elapsed += (sender, args) =>
            {
                Console.WriteLine("Timer elapsed.");
                completed.Set();
            };

            Console.WriteLine("Timer started.");
            timer.Start();
            completed.WaitOne();
        }
    }
}

WaitOne() maintient cet exemple console en vie jusqu’à ce que le gestionnaire d’événement signale l’achèvement. Dans une application à plus longue durée de vie, maintenez l’application en vie selon sa boucle d’événements normale ou la durée de vie de son service, au lieu d’ajouter une attente bloquante uniquement pour le minuteur.

Utiliser la classe System.Threading.Timer pour créer un délai en C#

System.Threading.Timer planifie un rappel avec un délai initial et une période. Les deux valeurs sont en millisecondes. Utilisez Timeout.Infinite pour la période lorsque le rappel ne doit s’exécuter qu’une fois ; fournissez une période finie pour planifier des rappels répétés. Le rappel s’exécute séparément du code qui démarre le minuteur.

Cet exemple complet planifie un rappel après deux secondes et l’attend avant de se terminer :

using System;
using System.Threading;

class DelayExample
{
    static void Main()
    {
        using (var completed = new ManualResetEvent(false))
        using (var timer = new System.Threading.Timer(
            state =>
            {
                Console.WriteLine("Timer callback.");
                completed.Set();
            },
            null,
            2000,
            Timeout.Infinite))
        {
            Console.WriteLine("Timer scheduled.");
            completed.WaitOne();
        }
    }
}

Le délai initial planifie le premier rappel deux secondes après la construction. Timeout.Infinite empêche la planification d’un autre rappel. L’attente maintient cet exemple console en vie assez longtemps pour recevoir le rappel ; une application dotée de sa propre boucle d’événements peut utiliser cette durée de vie à la place.

Conclusion

Utilisez Thread.Sleep() pour une pause synchrone simple lorsque le blocage du thread actuel est acceptable. Préférez Task.Delay() avec await dans le code asynchrone afin que la méthode puisse céder pendant l’attente. Choisissez System.Timers.Timer ou System.Threading.Timer lorsque vous avez besoin d’une planification basée sur des rappels, avec AutoReset ou la période du minuteur contrôlant la répétition. Les rappels de minuteur planifient du travail ; ils ne mettent pas en pause l’exécution séquentielle, et leur minutage n’est pas une garantie exacte d’horloge murale.