J'ai une fonction qui ajoute un contrôle à un contrôle parent qui est appelé à partir de threads différents du thread sur lequel les contrôles ont été créés. Voici comment ça se passe:opération cross-thread même lors de l'exécution sur le thread UI
1 delegate void AddControlToParentDelegate(Control child, Control parent);
2 private void addControlToParent(Control child, Control parent) {
3 if (parent.InvokeRequired) {
4 AddControlToParentDelegate d = new AddControlToParentDelegate(addControlToParent);
5 this.Invoke(d, new object[] { child, parent });
6 } else {
7 parent.Controls.Add(child);
8 }
9 }
10 }
Cela fonctionne bien jusqu'à deux parent.InvokeRequired
ainsi que child.InvokeRequired
sont vraies. Ensuite, une fois la ligne 5 exécutée (le délégué d
est appelé et la fonction est supposée s'exécuter sur le thread de l'interface utilisateur.) (Right?)) child
à la ligne 7 renvoie une exception invalide d'opération de threads croisés. Pourquoi est-ce? N'est-il pas déjà en cours d'exécution sur le thread il a été créé?
j'ai réussi à résoudre ce problème en ajoutant un chèque (child.InvokeRequired)
supplémentaire:
delegate void AddControlToParentDelegate(Control child, Control parent);
private void addControlToParent(Control child, Control parent) {
if (parent.InvokeRequired) {
AddControlToParentDelegate d = new AddControlToParentDelegate(addControlToParent);
this.Invoke(d, new object[] { child, parent });
} else {
if (child.InvokeRequired) {
this.Invoke(new MethodInvoker(delegate() {
parent.Controls.Add(child);
}));
} else {
parent.Controls.Add(child);
}
}
}
mais cela semble terriblement juste bidouille-y et inutile. Est-ce la façon de le faire? Ou ai-je totalement raté le bus?
En outre, des dessins qui ne * pas * utiliser 'InvokeRequired' sont plus maintenable. Je recommande de programmer une tâche sur le thread ui ou d'utiliser BackgroundWorker.ReportProgress, les deux étant des solutions indépendantes de la plate-forme (c'est-à-dire non liées à Windows Forms). –