J'ai un scénario. (Windows Forms, C#, .NET)
- Il y a un formulaire principal qui accueille un certain contrôle de l'utilisateur.
- Le contrôle utilisateur effectue des opérations lourdes sur les données, de sorte que si j'appelle directement la fonction
UserControl_Load
l'interface utilisateur devient non réactive pendant la durée d'exécution de la méthode de chargement. - Pour résoudre ce problème, je charge les données sur un fil différent (en essayant de modifier le code existant le moins possible).
- J'ai utilisé un fil de travail en arrière-plan qui chargera les données et qui, une fois terminé, informera l'application qu'il a fait son travail.
- Maintenant, un vrai problème est apparu. Toute l'interface utilisateur (formulaire principal et ses contrôles d'utilisateur enfants) a été créée sur le thread principal primaire. Dans la méthode LOAD du usercontrol, je récupère des données basées sur les valeurs d'un contrôle (comme une boîte de texte) sur le userControl.
Le pseudo-code ressemblerait à ceci :
CODE 1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
L'exception qu'il a donnée était
L'opération inter-filière n'est pas valide : Accès au contrôle depuis un thread autre que celui où il a été créé.
Pour en savoir plus, j'ai fait quelques recherches sur Google et une suggestion m'est apparue comme l'utilisation du code suivant
CODE 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be binded to grid at some later stage
}
}
MAIS MAIS MAIS... il semble que je sois de retour à la case départ. L'application est à nouveau devient non réactive. Cela semble être dû à l'exécution de la condition if de la ligne #1. La tâche de chargement est à nouveau effectuée par le thread parent et non par le troisième que j'ai créé.
Je ne sais pas si je l'ai bien ou mal perçu. Je suis novice en matière d'enfilage.
Comment puis-je résoudre ce problème et aussi quel est l'effet de l'exécution de la ligne 1 du bloc if ?
La situation est la suivante : Je veux charger des données dans une variable globale en fonction de la valeur d'un contrôle. Je ne veux pas changer la valeur d'un contrôle depuis le fil enfant. Je ne le ferai jamais à partir d'un thread enfant.
Il suffit donc d'accéder à la valeur pour que les données correspondantes puissent être récupérées dans la base de données.
0 votes
Pour mon cas particulier de cette erreur, j'ai trouvé la solution de contournement en utilisant un BackgroundWorker sur le formulaire pour gérer les parties du code nécessitant beaucoup de données. (i.e. mettre tout le code problématique dans la méthode backgroundWorker1_DoWork() et l'appeler via backgroundWorker1.RunWorkerAsync())... Ces deux sources m'ont orienté dans la bonne direction : stackoverflow.com/questions/4806742/ youtube.com/watch?v=MLrrbG6V1zM