Thread interruptibles - Besoin de conseils

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 - 31 juil. 2013 à 14:18
copperncius Messages postés 16 Date d'inscription vendredi 13 décembre 2013 Statut Membre Dernière intervention 30 août 2014 - 18 déc. 2013 à 18:08
Salut ta tou(te)s

J'ai une application dans laquelle je propose une TextBox de recherche.
Cette recherche est lancée dès que le contenu de la TB est modifié, afin de pouvoir proposer une liste d'Items.
Les données étant très nombreuses, la recherche complète dépasse les 3 ou 4 secondes et attendre 3 secondes à chaque lettre tapée n'est pas envisageable.

Je voudrais donc :
- lancer une recherche
- si la textbox est à nouveau modifiée, interrompre la précédente recherche afin d'en démarrer une autre

Je me suis orienté vers les Threads et j'ai trouvé des exemples avec les Threads interruptibles "Tasks", mais ceux-ci ne sont disponibles qu'à partir du Framework 4 et je suis obligé de rester avec mon Framework 2.

J'ai tenté de lancer ma tâche de recherche avec ça :
ThreadPool.QueueUserWorkItem(New WaitCallback( _
      AddressOf BuildSuggestedItemsList_xx))
+ un Booléen bAbort déclaré globalement que je bascule à True afin que la tâche en cours s'arrête (testée dans des If dans la tâche), mais la tâche lancée ne semble pas en tenir compte; je ne sais pas pourquoi.

Même pire :
Quand je vois qu'une précédente tâche est en cours, je mets mon bAbort à True puis j'attends dans une boucle
            Do While bSuggestedListInProgress
                Application.DoEvents()
            Loop
mais là, ça bloque la tâche précédemment lancée !
Je ne comprends pas pourquoi ...
Y a-t il une meilleure technique pour attendre ?

Vala
Jack [MVP VB]
NB : Je ne répondrai pas aux messages privés

11 réponses

Zermelo Messages postés 378 Date d'inscription samedi 22 septembre 2012 Statut Membre Dernière intervention 13 août 2017 14
31 juil. 2013 à 15:35
Bonjour cs_Jack.

Comment s'effectue la recherche en elle-même ? Il faudrait peut-être d'abord accélérer l'algorithme de recherche.

Cordialement.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
31 juil. 2013 à 19:16
Merci Zermelo, mais cette recherche s'organise autour de 3 bases de données et près de 200.000 données.
De plus, je suis obligé de les traiter l'une après l'autre et dans un certain ordre, donc pas possible de faire 3 threads (1 pour chaque DB).
C'est donc normal et j'ai déjà peaufiné cette partie.

Je crois que je vais utiliser un BackgroundWorker qui est Cancellable, mais faut que je trouve une astuce pour avoir accès à mes RecordSets ainsi qu'à la ListView qui doit accueillir les résultats. Pas gagné ...
0
Utilisateur anonyme
31 juil. 2013 à 19:30
Salut cs_Jack,

L'histoire ne précise pas pourquoi tu n'utilises pas la propriété AutoCompleteCustomSource du TextBox ?
http://msdn.microsoft.com/fr-fr/library/system.windows.forms.textbox.autocompletecustomsource.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Bon courage pour tes nouvelles fonctions sur ccm ;)
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
31 juil. 2013 à 19:53
Salut Banana et merci pour tes encouragements ;-)

AutoCompleteCustomSource : c'est par là que j'avais commencé, mais cet outil ne permet de trouver que les "mots commençant par", alors que j'ai besoin d'une recherche partielle + l'ambition de mettre au point (plus tard) un algo genre Radcliff (mots proches de)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
31 juil. 2013 à 20:08
Et Linq ne donne pas de bon résultats non plus ?

Option Strict On
Public Class Form1
    Dim mesitems As New List(Of String) From {"navet", "banane", "citron", "barbot"}
    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        Dim requete As IEnumerable(Of String) = From valeur As String In mesitems Where valeur.Contains(TextBox1.Text)

        Debug.Print("-------")
        For Each element As String In requete
            Debug.Print(element)
        Next

    End Sub
End Class


--
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
31 juil. 2013 à 20:20
Oups, voilà matière à travailler. Merci.
Sauf que mes items se trouvent dans des RecordSets et qu'il va falloir que j'approfondisse cette histoire de IEnumerable et voir comment faire le lien.

Hélas, je pars en déplacement ce soir et n'aurai pas l'occasion de replancher la question d'ici mardi.
Merci pour ces suggestions.
A+
0
Utilisateur anonyme
31 juil. 2013 à 20:32
Tu peux aussi étudier les "predicates" :
Option Strict On
Public Class Form1
    Dim mesitems As New List(Of String) From {"navet", "banane", "citron", "barbot"}

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        Dim resultats As List(Of String) = mesitems.FindAll(AddressOf Cherche)
        Debug.Print("-------")
        For Each resultat As String In resultats
            Debug.Print(resultat)
        Next
    End Sub

    Private Function Cherche(ByVal item As String) As Boolean
        If item.Contains(TextBox1.Text) Then Return True
        Return False
    End Function

End Class
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
2 août 2013 à 21:38
Je n'ai pas pu résister (pas tjrs facile en déplacement) à la mise en pratique de ces exemples.
Yearh !
Après la mise en pratique de la méthode 'predicate', la bufferisation (transformation des ADODB (de VB6) en Array de près de 180.000 données) + et la recherche (predicate) ne durent que 0.3 sec maxi !
Tout à fait acceptable.
Hyper supra cool !
Adieu les threads !

Un grand merci pour cette découverte.
(pitain fait chaud)
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
10 août 2013 à 20:47
Salut,

Pour la variable booléenne, es-tu certain que la procédure lancée atteigne la lecture de la variable avant que la procédure suivante ne positionne le paramètre sur False ?

Pour ce qui est de DoEvents, que veux-tu dire par bloque la tâche ? Que la variable bAbort fonctionne et que la procédure se termine ? Si c'est le cas ça rejoint ce que j'ai dis plus haut.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
12 août 2013 à 13:18
Merci Mayzz
Justement, c'était le problème majeur pour lequel je me posais la question :
Bien que ma variable bAbort soit déclarée en Public ET que ma longue procédure (que j'aimerai interrompre) ait des points de respiration (DoEvents), il semble que celle-ci, lancée par Thread, ne sache pas lire l'état de bAbort (cloisonnement ?).

Bref, "dis-moi ce qui te manque et je te dirai comment t'en passer" : Banana m'a envoyé sur une piste que je ne connaissais pas, les prédicates, et maintenant que j'ai testé (et compris) comment ça marche, j'en mets à toutes les sauces = Super efficacité = Plus besoin de Thread.
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
12 août 2013 à 19:55
"Plus besoin de Thread." => En effet, comme je le dis plus bas je n'avais pas vu les réponses elles n'étaient pas affichées. Ou peut être que je n'ai pas fait attention à cause du nouveau site.
0
Mayzz Messages postés 2813 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 2 juin 2020 28
10 août 2013 à 20:49
Mince désolé pour la réponse. Il y a eu un bug et les réponses ne se sont pas chargées. N'ayant pas vu celles-ci j'ai répondu comme si de rien était...
0
copperncius Messages postés 16 Date d'inscription vendredi 13 décembre 2013 Statut Membre Dernière intervention 30 août 2014
18 déc. 2013 à 18:08
bonsoir,
peut-etre si c'est possible de avoir une 4 ieme table qui contient le resultat des 3 autres tables, qui est actualisé quand une des trois tables à des changements
simplement une idée
frederic
0
Rejoignez-nous