Techniques progressBar sans mettre le traitement principal dans un Thread

  1. last year

    Nicolas J

    8 Nov 2018 Pre-Release Testers, Xojo Pro

    Bonjour,
    Je programme avec Xojo de manière intermittente et essaye en ce moment de mettre à jour un programme (AmplifX) que j'ai commencé à développer il y a 15 ans !
    Du coup à chaque fois je me heurte à de nouvelles évolutions qui m'obligent à reprendre pas mal de trucs.

    En l'occurence il s'agit de la mise à jour de l'interface (barre de progression et labels) pour permettre de voir la progression de taches lourdes.
    Dans ma précédente version (Xojo 2014 !) lors de l'exécution d'une tache (méthode ou event appelant éventuellement d'autres méthodes avec pleins de boucles dans tous les sens), j'avais créé une fenêtre de progression que je faisais apparaitre et qui se redessinait lorsque je lui demandais depuis les différentes méthodes de la tache de calcul.
    Ca marchait meme sous Cocoa mais ca ne marche plus maintenant !
    J'ai bien vu ce qui est recommandé : tache principale dans un thread qui met à jour une propriété globale d'avancement de la tache, et mise à jour de l'interface (progresserBar ou autre) par une timer.
    Mais comme mon programme effectue beaucoup de taches différentes, cela ne me semble pas raisonnable de toutes les mettre dans des threads (car ca va être super compliqué à faire, y compris avec AddHandler et va poser des problèmes complexes de vérif de fin de tache, voire meme de diminution de performances meme en mettant une valeur élevée à priority, il me semble)
    Bref, est-ce que quelqu'un a une autre astuce ou on ne peut définitivement pas faire autrement.
    Autrement dit, est-ce que le main thread ne peut pas laisser la main à un thread secondaire de faible priorité qui pourrait lui s'occuper de la mise à jour de l'UI (par le biais d'un timer peut être); J'ai fait pleins d'essai dans ce sens mais rien ne marche (le timer ne "fire" pas) mais peut être j'ai loupé une possibilité.
    J'espère avoir été assez clair :-(
    Nicolas

  2. Salut Nicolas,

    les mises-à-jour de l'UI ne peuvent plus se faire depuis un Thread autre que le main Thread. Donc un Thread secondaire ne te servira à rien.

    À mon avis, le mieux pour toi serait de :
    • Adopter partiellement les recommandations (mettre-à-jour une variable globale et utiliser un Timer (qui est toujours exécuté dans le Main Thread) pour répercuter les changements dans l'UI)
    • Utiliser App.DoEvents à des endroits clef de ton code pour permettre au Timer de s'exécuter

    Ce n'est pas l'idéal, mais ça devrait fonctionner.

  3. Nicolas J

    8 Nov 2018 Pre-Release Testers, Xojo Pro

    Bonjour Stéphane
    et merci pour ta réponse.

    J'ai pas trop regardé le DoEvent car sur le forum (en englishe) de nombreux contributeurs déconseillent fortement de l'utiliser.
    Par exemple :

    @Kem T Do not do that. Never do that. Ignore anyone who tells you to do that. (Sorry Christoph.)

    Mais bon s'il n'y que ca à faire, je vais regarder...

    Encore merci.

  4. Jean-Yves P

    8 Nov 2018 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    je n'utiliserait pas le doevent non plus ... à enlever des que possible et rempalcer par un timer.

  5. Je suis d'accord avec Kem mais je t'ai proposé cette solution parce que tu as clairement indiqué que tu ne souhaitais pas mettre tout ton code dans un Thread. Or c'est soit ça, soit utiliser App.DoEvents.

    Si tu veux aller vite, App.DoEvents est facile à mettre en œuvre, mais un jour ou l'autre, il faudra probablement modifier ton logiciel de façon plus drastique et en venir aux Threads.

  6. Nicolas J

    8 Nov 2018 Pre-Release Testers, Xojo Pro

    Merci à tous les deux.
    Du coup est-ce que tout le monde dans la communauté a été obligé de re-écrire de grosses parties de programmes ?
    C'est quand meme fou, je trouve, de devoir affronter de tels changements.
    Le pire étant qu'en plus dans les Threads "secondaires" (je les appelle comme ca par opposition au "Main thread", mais je sais pas si c'est nécessaire) on ne peut pas du tout interagir avec l'interface. Mais en programmation objet beaucoup d'éléments font partie de l'interface y compris par exemple pour moi des objets ayant pour vocation de rentrer dans les différents calculs.
    Bientôt ca va être plus facile de faire de l'Objective C ou Swift si ca continue :-(

  7. Eh bien, à ma connaissance, ce n'est pas Xojo qui a requis ce genre de changement mais bel et bien les systèmes d'exploitation qui ont imposé ça, mais pour de bonnes raisons.

    Donc il a bien fallu s'y faire

  8. Nicolas J

    8 Nov 2018 Pre-Release Testers, Xojo Pro

    Oui oui j'avais compris (un peu tard ;-) ) que c'est les version 64 bits des OS qui imposent ca pour pleins de raisons valables probablement. Mais c'est juste que du coup, je vois plus comment on peut faire du RAD dans ces conditions.

    Je viens d'essayer DoEvent. Ca fait "la job". Mais meme sur un essai tout simple je vois déjà les problèmes à venir : ralentissements très notable des calculs et risque que l'utilisateur aille activer un menu ou cliquer sur un bouton

  9. Avec tes calculs dans un Thread différent, la vitesse va s'améliorer. En revanche, l'utilisateur va toujours pouvoir faire des choses que tu ne souhaites pas en tant que développeur (mais qui te sembleraient normales en tant qu'utilisateur).

    Tu peux toujours essayer de dire à tes utilisateurs que "il ne faut pas bouger la souris après avoir cliqué sur 'OK'"... mais qui va vraiment le faire ? Et qui ne va pas se plaindre ?

  10. 12 months ago

    Jean L

    14 Dec 2018 Pre-Release Testers, Xojo Pro Sud Paris

    Pour résoudre le problème, il faut afficher une fenêtre modale pendant la durée du traitement

  11. Jean L

    15 Dec 2018 Pre-Release Testers, Xojo Pro Sud Paris

    va voir la documentation sur Thread tout est expliquer comment faire

  12. Thomas R

    16 Dec 2018 Europe, France, Besancon

    Je pense que c'est le problème des DoEvents, de relancer une seconde fois la même tâche (la même procédure). Il y en aurait 2 (ou plus) de lancer en même temps qui pourraient modifier les mêmes variables globales.

    Avant j'avais des DoEvents mais je bloquais toute l'interface, sauf les menus/boutons qui permettaient de stopper le process en cours. M'étant retrouvé au chômage, j'ai tout modifié mes 11 programmes pour tout mettre dans des Threads ou des Timers. Mais pfff ça a été du boulot.

    Les Timers sont une autre solution. De temps en tant tu sors de la boucle (qui est dans le Timer) en mémorisant où tu en es. Là l'UI reprend la main, puis tu relances ton Timer après un court temps (donc ta boucle reprend là où tu l'as laissée).
    L'avantage de la méthode du Timer c'est que tu peux lire et écrire dans ton interface (TextField, ProgressBar etc.). Alors que dans un Thread tu dois passer par des variables.

  13. 10 months ago

    J'ai un seul ModalAttenteProgress... dans ma webpage je me crée autant d'objet que j'ai besoin de process avec comme référence ModalAttenteProgress... et je nomme ces objets significatifs... Dans le script au point progress j'y insère "objmonscript.show" et tout le script qui suit est mis dans mon event "action" de mon objet "objmonscript"... et ca fonctionne toujours très bien.

  14. Valdemar D

    23 Jan 2019 Pre-Release Testers, Xojo Pro Europe ( France, Paris )

    As-tu essayé le module Task ? une subclass du Thread qui implémente un UpdateUI dans ses événement. https://www.dropbox.com/sh/3tiom71xip6ch51/AAAexsX3cXloCt5c4ESRhzZUa?dl=0

or Sign Up to reply!