IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

surlignage richtexbox trop lent [Débutant]


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    autodidacte
    Inscrit en
    Décembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2014
    Messages : 20
    Points : 12
    Points
    12
    Par défaut surlignage richtexbox trop lent
    coucou ,
    actuellement j'essaye de trouver un moyen d'accélérer une recherche de mot d'un texte dans une richtextbox.
    sur des textes assez gros je me rend vite compte de la lenteur d'une boucle avec la méthode select .
    j'ai essayé autre chose avec le format Rtf , pour modifier la couleur des mots recherchés et affiché le texte en seule fois , mais je trouve pas ça pratique à coder et je galère un peu .
    auriez vous des techniques ou des idées pour optimiser ce genre de pb ?
    Merci

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 183
    Points : 5 754
    Points
    5 754
    Par défaut
    Essaye de stopper le rafraichissement de ta richtextbox durant ton traitement de mise à jour

    Méthode d’extension :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        public static class ControlExtensions
        {
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            public static extern bool LockWindowUpdate(IntPtr hWndLock);
     
            public static void Suspend(this Control control)
            {
                LockWindowUpdate(control.Handle);
            }
     
            public static void Resume(this Control control)
            {
                LockWindowUpdate(IntPtr.Zero);
                // this.Invalidate(); // Peut être nécessaire ou pas à tester
            }
     
        }
    Utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TextBox1.Suspend();
    // Mise à jour ...
    TextBox1.Resume();

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Pour afficher un RichTextBox avec un Rtf sur des très gros texte, ça pose problème en temps de chargement du texte, en temps de recherche,...
    Bref, utiliser RichTextBox pour des textes long pose problèmes sur plusieurs points.

    Je t'apporte donc une solution que j'ai élaborée:
    1-l'idée consiste d'abord à stocker chaque ligne à afficher dans un tableau de string.
    2-Ensuite, il suffit de n'afficher dans le richTextBox que les lignes visibles. Là, tu gagne un temps considérable en rapidité de chargement du texte et d'affichage
    3- Il faudra ensuite redéfinir la gestion des évènement (scrolling,flèches,...) pour n'afficher que les lignes dont tu as besoin.
    4- pour la recherche de mots clé, là aussi, tu gagnes un temps considérable, puisque la recherche se fait uniquement dans le tableau de string et de réafficher les bonnes lignes dans le richtextBox.

    Pour faire toutes ces modifications, le mieux est de définir une classe dérivée de richtextBox dans un control personnalisé qui contient toutes ces modifications.

  4. #4
    Membre à l'essai
    Homme Profil pro
    autodidacte
    Inscrit en
    Décembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2014
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    merci ecriclm128 je vais déjà tester ta solution ,

    merci aussi à toi helices cependant je suis déjà passé par un tableau de strings pour accélérer la recherche , qu'entends tu par lignes visibles ? ( les lignes contenant le mot recherché ? )
    ça m'interresse de savoir comment tu fais pour garder toutes les sélections du mots recherché au moment de l'affichage des lignes dans le richtexbox . ( car la methode sélection passe que par le richtexbox et pas par le tableau )
    à la rigueur je peux modifier la couleur des mots en les modifiant les lignes qui le contiennent , mais je passe aussi par un "colordialog" , ce qui va compliquer un peu la chose.

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Par exemple, si ton texte contient 100000 lignes et que ton richtextBox ne peut (exemple) en afficher que 17 à l'écran.

    Tu n'auras que 17 lignes visibles de ton texte que tu affiches dans le richTextBox.

    Il te suffit de décaler (translater) ta fenetre de 17 lignes consécutives parmi les 100000 dans ton richtextBox: par exemple ligne[20] à ligne[20+17], en redéfinissant le contenu richtextBox.Rtf à chaque fois.

    Pour la recherche de mot clé, si tu souhaites seulement surligner ce qui est visible dans le richtextBox, tu peux très bien lancer une recherche classique avec les méthodes de richtextBox.

    Seulement, si tu souhaites effectuer une recherche descendante (à partir de la ligne[20+17]) ou montante (à partir de la ligne[20]), il te faudrait faire une recherche sur le tableau des lignes, afin d'afficher la nouvelle fenêtre lorsqu'un mot sera trouvé sur ces nouvelles 17 lignes.

    Quand aux couleurs, tu peux imaginer un tableau à 2 dimensions [index de ligne][maximum caractères] où tu définit la couleurs de chaque caractères. Quand tu utilise ton ColorDialog, tu remodifies ce tableau pour garder en mémoire les nouvelles couleurs.

  6. #6
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 183
    Points : 5 754
    Points
    5 754
    Par défaut
    Je revient sur le problème d'origine , pourrait tu nous donner ton code lent ?
    Que je comprenne ce que tu veux faire exactement ?

  7. #7
    Membre à l'essai
    Homme Profil pro
    autodidacte
    Inscrit en
    Décembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2014
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    je mets la finalité de mon code qui consiste à rechercher un mot ds un texte d'une richtexbox.

    foreach (int index in indexmot ) { richTextBox1.Select(index, LongMot); richTextBox1.SelectionBackColor = Coul; }
    indexmot correspond à une table qui contient toutes les positions du mot recherché ds le texte
    coul correspond à la couleur du colordialog

    et comme dit juste avant cette boucle pose problème dans un très gros texte , si le mot recherché y est présent par exemple 1 000 000 de fois , on voit l'affichage des sélections défiler lentement ds le richtexbox.

    c'est suite à ce pb , que j'ai pensé à modifier le texte en mode rtf afin que le mot recherché soit en couleur via codage rtf , pour au final n'avoir qu'un affichage en une seule fois du texte modifié, mais ça devient une usine à gaz.
    c'est pour ça que la solution de stopper le rafraichissement me semble assez pertinente.

  8. #8
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 183
    Points : 5 754
    Points
    5 754
    Par défaut
    Et tu as essayé alors ?

  9. #9
    Membre à l'essai
    Homme Profil pro
    autodidacte
    Inscrit en
    Décembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2014
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    oui j'ai testé ,et j'ai mesuré le temps d’exécution mais ça n'a rien changé , la rapidité d’exécution reste la même

  10. #10
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 183
    Points : 5 754
    Points
    5 754
    Par défaut
    Hello j'ai un peu travaillé sur ton problème.

    J'ai tenté, sans succès avec SuspendLayout et ResumeLayout (rien de significative).

    J'ai donc chercher à générer le code rtf moi même pour lui injecter avec 'richTextBox1.Rtf = '.
    Je passe de 3,10s à 1,36s sur mon test.

    Ne comprenant pas pourquoi c'était toujours aussi long j'ai chercher. Finalement c'est l'ajout du rtf formaté à 'richTextBox1.Rtf' qui met un temps monstre, il doit digérer les données transmises certainement.
    Si je met en commentaire cette ligne, pour vérifier mon temps de traitement, j’obtiens 0,00467 s.

    J'ai tenter de wrapper une autre version du contrôle RichTextBox plus performante (RichEdit50W), il y avait des problèmes de performance avec celle la (RichEdit20W)
    http://stackoverflow.com/questions/1...inutes-loading
    http://stackoverflow.com/questions/3...ll-rtf-content

    Voici les résultats :
    RichEdit50W + méthode 'Select + SelectionBackColor' -> 0,86 s
    RichEdit50W + méthode de formatage manuelle du RTF -> 0,05 s

    Conclusion :
    1) Utilise le 'RichTextBox' de la version la plus récente 'RichEdit50W' il est 3,6 fois plus rapide sur mes tests.
    2) Si tu veux gagner encore en performance, formate manuellement le RTF et donne lui tout fait, la par contre il y a du développement (j'ai fait un test en mode "cochon"). La on est 60 fois plus rapide sur mes tests.
    3) tu peux aussi chercher un autre contrôle personnalisé, redéveloppé (pas un simple contrôle dérivé de RichTextBox), plus performant.

  11. #11
    Membre à l'essai
    Homme Profil pro
    autodidacte
    Inscrit en
    Décembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2014
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    ok je vais travailler sur tes solutions proposées.
    J'espère qu'un jour ils proposeront des méthodes de recherches bien plus performantes pour les gros textes.
    Merci en tout cas d'avoir pris le temps de chercher et de m'aider

  12. #12
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 183
    Points : 5 754
    Points
    5 754
    Par défaut
    Oui mais ce n'est pas la recherche qui ralenti en faite

    Moi j'ai piqué cette méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
            public static List<int> AllIndexesOf(this string str, string value)
            {
                if (String.IsNullOrEmpty(value))
                    throw new ArgumentException("the string to find may not be empty", "value");
                List<int> indexes = new List<int>();
                for (int index = 0; ; index += value.Length)
                {
                    index = str.IndexOf(value, index);
                    if (index == -1)
                        return indexes;
                    indexes.Add(index);
                }
            }
    Une dernière optimisation peut être, cette méthode me donne 3 occurrences (0, 2, 4), si elles sont contiguës ce serait plus rapide au traitement de ne considéré quelle ne font qu'une seule occurrence de 6 caractères.
    List<int> resultat = "aaaaaa".AllIndexesOf("aa");

  13. #13
    Membre habitué
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 72
    Points : 135
    Points
    135
    Par défaut
    Bonjour,

    Tu pourrais aussi utiliser une autre méthode.

    Tu lances la recherche, stocke la position de chaque occurrences, mais ne formate que le texte qui est effectivement affiché sur l'écran, voir depuis n lignes avant et n lignes après. Tu mets à jour lorsque tu navigues à l'intérieur de ton richtextbox.

    Amicalement,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Convolution trop lente...
    Par progfou dans le forum Traitement d'images
    Réponses: 6
    Dernier message: 05/08/2006, 11h44
  2. [Eclipse] Editeur de code trop lent
    Par Benzeghiba dans le forum Eclipse Java
    Réponses: 6
    Dernier message: 10/11/2005, 14h02
  3. boucle while trop lente
    Par atouze dans le forum Access
    Réponses: 17
    Dernier message: 15/06/2005, 16h35
  4. [SAGE] ODBC trop lent
    Par tileffeleauzed dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 14/11/2004, 09h56
  5. Envoi de mail trop lent
    Par MASSAKA dans le forum ASP
    Réponses: 3
    Dernier message: 15/10/2004, 10h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo