Meilleur auteur de réponses
Placer un code dans un BackGroundWorker

Question
-
Bonjour,
Je voudrais mettre ce code ci-dessous dans un backgroundworker sens qu'il y est ce message d'erreur :
- Cross-thread operation not valid: Control 'ListView' accessed from a thread other than the thread it was created on.
Voici le code que je voudrais mettre dans un BackGroundWorker :
Dim obj As New cls_film_search
Dim Mov As cls_movie_tags
Me.Listview1.Items.Clear()
For Each mov In cls_film_search.get_propositions(Me.Textbox1.Text)
Dim elt As New ListViewItem
elt.Text = mov.title
elt.Tag = mov
ListView1.Items.Add(elt)
Next
End Sub
- Ce bout de code (incomplet) permet de faire une recherche dans une page html....
Merci d'avance pour votre aide.
Réponses
-
Lors de l'appel : bgw.RunWorkerAsync(Me.Textbox1.Text)
Dans le DoWork tu récupère le texte qui est en argument :
bgw_DoWork(
Dim obj As New cls_film_search
Dim Mov As cls_movie_tags
Dim MonTexte As String
MonTexte = e.Argument.ToString()
For Each mov In cls_film_search.get_propositions(MonTexte )
Dim elt As New ListViewItem
elt.Text = mov.title
elt.Tag = mov
((BackgroundWorker)sender).ReportProgress(0, elt) '<- Envoie l'information au ProgressChanged
Next
end sub
Et tu récupère l'infos dans le ProgressChanged :
bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
(ListViewItem)e.UserState
Voilà en gros à quoi cela ressemble. Désolé pour la syntaxe, moi je code en C#... Mais en gros c'est comme cela que cela se fait. Dans le doWork je fais tout le traitement qui consomme du temps, sans jamais appelé des objets de mon interface (Qui ont été créé dans un autre thread) et j'utilise la méthode ProgressChanged (Qui est dans le même thread que l'interface) pour mettre à jour mon interface.
Toutes les réponses
-
Tu ne peux pas accèder aux contrôles d'une interface dans le DoWork d'un background Worker. Tu dois utiliser les méthodes ProgressChanged( avec l'appel de ReportProgress dans le DoWork backgroundworker) et RunWorkerCompleted.
Tu peux passez des arguments à ces 2 méthodes. Mais attention, mettre à jour aussi souvent l'interface va quand même faire geler ton application, donc pas intéressant d'utiliser le backgroundworker.
Tu peux allez voir http://msdn2.microsoft.com/fr-fr/library/system.componentmodel.backgroundworker_members(VS.80).aspx et http://msdn2.microsoft.com/fr-fr/library/system.componentmodel.backgroundworker(VS.80).aspx
-
-
Pourquoi désirais tu un BackgroundWorker (BGW) au départ, es-ce que la tâche que tu lance est longue, car tu peux utiliser le BGW. Tu passe ton texte que tu as dans ton textbox a ton BGW, et tu fais un reportProgress(0,elt).
puis dans le ProgressChanged, tu prend l'argument et tu l'ajoute a ton listView et cela devrait fonctionner. La fonction ProgressChanged est dans le même thread que l'interface, donc tu peux utiliser ton listview.
-
-
Lors de l'appel : bgw.RunWorkerAsync(Me.Textbox1.Text)
Dans le DoWork tu récupère le texte qui est en argument :
bgw_DoWork(
Dim obj As New cls_film_search
Dim Mov As cls_movie_tags
Dim MonTexte As String
MonTexte = e.Argument.ToString()
For Each mov In cls_film_search.get_propositions(MonTexte )
Dim elt As New ListViewItem
elt.Text = mov.title
elt.Tag = mov
((BackgroundWorker)sender).ReportProgress(0, elt) '<- Envoie l'information au ProgressChanged
Next
end sub
Et tu récupère l'infos dans le ProgressChanged :
bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
(ListViewItem)e.UserState
Voilà en gros à quoi cela ressemble. Désolé pour la syntaxe, moi je code en C#... Mais en gros c'est comme cela que cela se fait. Dans le doWork je fais tout le traitement qui consomme du temps, sans jamais appelé des objets de mon interface (Qui ont été créé dans un autre thread) et j'utilise la méthode ProgressChanged (Qui est dans le même thread que l'interface) pour mettre à jour mon interface.
-
Merci encore une fois pour ta réponse ;)
J'ai crée le code comme tu la expliqué mais j'ai ce message d'erreur lors de l'éxécution du programme :
This BackgroundWorker states that it doesn't report progress. Modify WorkerReportsProgress to state that it does report progress.
D'aprés ce que j'ai compris au message je dois modifier sa :
Me.BackgroundWorker1.RaportProgress(0, elt) ?
-
Non, en fait tu dois dire au BGW que permet de rapporter la progression (Cela devrait selon moi être a vrai tout le temps, mais par défaut, il ne supporte ni le rapport de progression ni l'annulation).
Soit que tu vas dans le designer et tu mets la propriété du BGW WorkerReportsProgress = True ou par le code :
Me.BackgroundWorker1.WorkerReportsProgress = true
J'oublie toujours ce petit détail, ne pense pas que je voulais te cacher quelque chose :)
-
Merci beaucoup pour ton aide !!! Sa ma beaucoup aider ! Sa fonctionne a merveille :D
Si tu as Live Messenger voici mon adresse : blaster681@hotmail.com je serais ravis de t'envoyer le résultat ;)
Merci beaucoup a toi ;)