Gestion des temporisateurs dans les applications Windows Forms

Les applications Windows Forms nécessitent souvent l'exécution de tâches à intervalles réguliers. Deux approches courantes impliquent l'utilisation de System.Timers.Timer ou la création d'un thread dédié. Ces méthodes permettent de mettre à jour l'interface utilisateur de manière périodique, mais elles doivent gérer correctement les threads pour éviter les exceptions.

Utilisation de System.Timers.Timer

Le composant System.Timers.Timer déclenche un événement à intervalles fixes. Il est idéal pour des tâches simples nécessitant une exécution répétée. Voici un exemple de mise en œuvre :


public partial class FormulairePrincipal : Form
{
    private System.Timers.Timer horloge;
    private int compteurTotal = 0;
    private int partieMillier;
    private int partieCentaine;
    private int partieDizaine;
    private int partieUnite;

    public FormulairePrincipal()
    {
        InitializeComponent();
    }

    private void FormulairePrincipal_Load(object sender, EventArgs e)
    {
        champTexte.Text = "00.00";
        horloge = new System.Timers.Timer(1000);
        horloge.Elapsed += TraiterInterruptionTimer;
        horloge.AutoReset = true;
    }

    private void TraiterInterruptionTimer(object source, System.Timers.ElapsedEventArgs evt)
    {
        compteurTotal++;
        partieMillier = compteurTotal / 1000;
        partieCentaine = (compteurTotal % 1000) / 100;
        partieDizaine = (compteurTotal % 100) / 10;
        partieUnite = compteurTotal % 10;
        this.Invoke((MethodInvoker)delegate {
            champTexte.Text = $"{partieMillier}{partieCentaine}.{partieDizaine}{partieUnite}";
            listeMessages.Items.Insert(0, "Notification temporelle");
        });
    }

    private void boutonActiver_Click(object sender, EventArgs e)
    {
        horloge.Enabled = true;
    }
}

Dans ce code, Invoke garantit que les mises à jour de l'interface utilisateur s'effectuent sur le thread principal, évitant ainsi les erreurs de thread croisé.

Création d'un thread dédié

Pour des tâches plus compleexs, un thread séparé peut être lancé pour exécuter une boucle planifiée. Cette méthode offre plus de flexibilité mais nécessite une gestion minutieuse des threads.


public partial class FormulairePrincipal : Form
{
    private Thread filExecution;
    private int compteurTotal = 0;
    private int partieMillier;
    private int partieCentaine;
    private int partieDizaine;
    private int partieUnite;

    public FormulairePrincipal()
    {
        InitializeComponent();
    }

    private void FormulairePrincipal_Load(object sender, EventArgs e)
    {
        champTexte.Text = "00.00";
        filExecution = new Thread(BoucleTachePlanifiee);
        filExecution.IsBackground = true;
    }

    private void BoucleTachePlanifiee()
    {
        while (true)
        {
            compteurTotal++;
            partieMillier = compteurTotal / 1000;
            partieCentaine = (compteurTotal % 1000) / 100;
            partieDizaine = (compteurTotal % 100) / 10;
            partieUnite = compteurTotal % 10;
            this.Invoke((MethodInvoker)delegate {
                champTexte.Text = $"{partieMillier}{partieCentaine}.{partieDizaine}{partieUnite}";
            });
            Thread.Sleep(1000);
        }
    }

    private void boutonActiver_Click(object sender, EventArgs e)
    {
        filExecution.Start();
    }
}

Ici, le thread s'exécute en arrière-plan avec une pause d'une seconde entre chaque itération. L'utilisation de Invoke reste essentielle pour manipuler les contrôles d'interface.

Bonnes pratiques pour les threads dans WinForms

L'accès direct aux contrôles depuis un thread non-UI peut entraîner des exceptions de thread interdit. Il est recommandé d'utiliser Invoke ou BeginInvoke pour les mises à jour. Désactiver les vérifications avec Control.CheckForIllegalCrossThreadCalls = false est une solution de contournement déconseillée, car elle masque des problèmes de concurrence potentiels.

Le choix entre System.Timers.Timer et un thread dédié dépend des exigences de l'application : le premier est plus simple pour des intervalles réguliers, tandis que le second offre un contrôle accru pour des tâches asynchronse complexes.

Étiquettes: WinForms CSharp System.Timers.Timer Thread UI Threading

Publié le 11 juin à 22h14