Maison >développement back-end >C++ >Comment mettre à jour en toute sécurité les contrôles de l'interface utilisateur à partir d'un thread distinct en C# pour éviter les exceptions entre threads ?

Comment mettre à jour en toute sécurité les contrôles de l'interface utilisateur à partir d'un thread distinct en C# pour éviter les exceptions entre threads ?

Linda Hamilton
Linda Hamiltonoriginal
2025-01-23 02:26:10745parcourir

How to Safely Update UI Controls from a Separate Thread in C# to Avoid Cross-Thread Exceptions?

Éviter les exceptions cross-thread en C# : mettre à jour en toute sécurité les contrôles de l'interface utilisateur

Le problème : Les applications C# rencontrent souvent des exceptions « Opération inter-thread non valide » lors de la mise à jour des contrôles de l'interface utilisateur à partir de threads autres que le thread principal de l'interface utilisateur. Cela se produit généralement lors du traitement de données provenant de sources externes, comme le port UART d'un microcontrôleur, dans un thread séparé.

Scénario : Imaginez un microcontrôleur envoyant des données de température via UART. Votre application C# reçoit ces données dans un thread d'arrière-plan, mais tenter de mettre à jour directement un TextBox avec la valeur de température lève l'exception.

Cause première : Les contrôles de l'interface utilisateur sont liés au fil de discussion sur lequel ils sont créés. Y accéder à partir d'un autre fil de discussion viole cette règle.

La solution : tirer parti du répartiteur

La clé pour résoudre ce problème consiste à utiliser le répartiteur, un mécanisme qui garantit que les mises à jour de l'interface utilisateur se produisent sur le bon fil de discussion. Il s’agit d’un modèle simple mais efficace :

  1. Créer un délégué : Définir un délégué pour encapsuler l'opération de mise à jour de l'interface utilisateur :

    <code class="language-csharp">delegate void SetTextCallback(string text);</code>
  2. Implémentez la méthode de mise à jour : Cette méthode vérifie si le fil de discussion actuel est le fil de l'interface utilisateur. Sinon, il utilise Invoke pour regrouper la mise à jour vers le fil de discussion de l'interface utilisateur :

    <code class="language-csharp">private void SetText(string text)
    {
        if (this.textBox1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox1.Text = text;
        }
    }</code>
  3. Mise à jour depuis le fil de discussion en arrière-plan : Dans votre gestionnaire d'événements serialPort1_DataReceived (ou équivalent), appelez la méthode SetText après avoir reçu les données :

    <code class="language-csharp">private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string receivedData = serialPort1.ReadExisting();
        SetText(receivedData); 
    }</code>

Cette approche garantit que toutes les mises à jour de l'interface utilisateur sont effectuées en toute sécurité sur le thread principal de l'interface utilisateur, empêchant ainsi l'exception entre threads. La vérification InvokeRequired gère efficacement la situation dans laquelle la mise à jour se trouve déjà sur le bon fil de discussion, évitant ainsi une surcharge inutile.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn