É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 :
Créer un délégué : Définir un délégué pour encapsuler l'opération de mise à jour de l'interface utilisateur :
delegate void SetTextCallback(string text);
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 :
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; } }
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 :
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string receivedData = serialPort1.ReadExisting(); SetText(receivedData); }
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!