1. Ce site utilise des cookies. En continuant à utiliser ce site, vous acceptez l'utilisation des cookies. En savoir plus.
  2. Bonjour tout le monde ! Veillez consulter la Politique de forum pour comprendre nos règles, Merci a vous !
    Rejeter la notice

AIDE Webservice et thread secondaire/Tâches parallèles

Discussion dans 'Windev' créé par MayBst, Mai 21, 2019.

  1. MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15
    Bonjour bonjour,

    Je viens faire appel à une bonne âme pour m'aider dans cette réflexion.

    Je vous replace le contexte. Je créée une application de point de vente, qui donc doit être réactive. Mais la base de données n'est accessible que via webservice.
    Globalement, pas trop de soucis. Sauf pour l'enregistrement des lignes de facture.
    Je suis obligée à chaque sortie de ligne de les envoyer au webservice car certains traitements doivent être fait dans l'application mère (que je ne gère pas et sur laquelle je n'ai pas la main) et d'attendre la fin de son traitement pour afficher certaines cellules de ma table ainsi que des champs de ma fenêtre. Et c'est un peu long. Bon on parle d'une seconde ou deux, mais connaissant le client, c'est déjà trop pour lui.
    J'ai pensé à passer par des tâches parallèles, mais comme je dois attendre la fin du traitement pour afficher des informations, ça me bloque tout et c'est comme si je n'avais pas de tâche parallèle. Donc inutile.
    J'ai bien pensé au thread, mais que ce soit dans la doc ou dans windev, ils ne cessent d'expliquer que ce n'est pas fait pour changer de l'IHM.

    Du coup je me tourne vers vous. Que pourrais-je faire selon vous ?

    Merci par avance !
     
  2. khaliassas

    khaliassas Active Member

    Inscrit:
    Mar 4, 2019
    Messages:
    446
    J'aime reçus:
    142
    salut. le thread secondaire ou tache parallele ne doit pas toucher a l'ihm
    mais si tu exécute toute tes tache parallèle en thread principal elle sont bloquante donc aucun intérêt de les utiliser.

    mais globalement tache parallele ou thread secondaire il faut faire uniquement les calculs puis a la fin exécuter une procédure qui modifie l'ihm

    en gros fin de ligne --> thread secondaire(interroge webservice) --> renvoie résultat au thread principal : tu modifie l'ihm.
    après c'est jouable si chaque ligne est indépendant et ne nécessite pas des info de la ligne du dessus.
     
    MayBst apprécie ceci.
  3. MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15
    Pour attendre le résultat du thread secondaire je dois faire une procédure interne à ce dernier dans laquelle je fais mon traitement sur l'IHM, c'est cela ?
     
  4. PhantomX

    PhantomX Member

    Inscrit:
    Juil 11, 2018
    Messages:
    78
    J'aime reçus:
    61
    Bonjour,

    Code (Windev):

    soit t1 = TâcheParallèleExecute(_ProcCalcul, (Param1, Param2), tpoCopieDifféréeContexteHFSQL)
    TâcheParallèleExécuteAprès(t1, _ProcAffichage, (ValeurRenvoyéeTâchePrécédente), tpoThreadPrincipal)


    // Si tu as plusieurs calcul différent, tu peut stocké tes taches dans un tableau de tache parllèlles

    tt est un tableau de TâchesParallèles

    soit t1 = TâcheParallèleExécute(_ProcCalcul, (Param1, Param2), tpoCopieDifféréeContexteHFSQL)
    tt.

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    (t1)
    soit t2 = TâcheParallèleExécute(_ProcCalcul, (ValeurRenvoyéeTâchePrécédente), tpoCopieDifféréeContexteHFSQL)
    tt.

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    (t2)
    TâcheParallèleExécuteAprèsToutes(tt, _ProcAffichage, (), tpoThreadPrincipal)
     

    Tu n'est pas obligé de mettre tes procédure en Procédure Interne, ce peut être des procédure local ou global, ça fonctionne aussi

    Fait attention si tu déclare des variables globales d'écrire <section critique> au bout de ta variable (Res est un entier <section critique>) pour éviter les conflits dans les accès, (version 21 ou 22 je crois pour l'attribut <section critique> sinon c'est SectionCritiqueDebut() et SectionCritiqueFin()
     
  5. MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15
    Merci pour ta réponse. Je vais essayer et je te dis.
     
  6. MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15
    Rebonjour,

    J'ai essayé ce que tu m'as conseillé. Déjà, l'exécution est effectivement plus rapide ainsi concernant les webservices.
    En revanche, en utilisant TâcheParallèleExécuteAprès, qu'il s'agisse d'une procédure interne ou locale, une erreur se déclenche, il ne reconnait pas mes champs.

    J'ai alors essayé de faire juste un info dans cette procédure là et l'erreur a été plus claire :
    La fonction 'Info' est interdite dans une tâche parallèle.
    Utilisez une tâche de continuation ou une procédure à exécution dans le thread principal pour manipuler les champs.

    Pourtant dans la doc, il est bien indiqué que cette procédure là est une procédure de continuation.

    ... Et je m'aperçois à l'instant que j'avais omis "tpoThreadPrincipal", ce qui effectivement règle le soucis.

    Je réessaie avec mon IHM : C'est nickel !

    Merci :D
     
  7. PhantomX

    PhantomX Member

    Inscrit:
    Juil 11, 2018
    Messages:
    78
    J'aime reçus:
    61
    tu peux aussi, à l'intérieur de ta procédure de ta tache parallèle utiliser :

    ExécuteThreadPrincipal(_ProcIHM)

    Ceci évite de lancer une TacheParalleleExecuteApres

    Tout dépend de tes besoins.
     
    MayBst apprécie ceci.
  8. khaliassas

    khaliassas Active Member

    Inscrit:
    Mar 4, 2019
    Messages:
    446
    J'aime reçus:
    142
    en version thread secondaire

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    tu peux aussi, à l'intérieur de ta procédure de ta tache parallèle utiliser :

    ExécuteThreadPrincipal(_ProcIHM)

    Ceci évite de lancer une TacheParalleleExecuteApres

    Tout dépend de tes besoins.
    Cliquez pour agrandir...
    oui meme methode avec les thread secondaire...

    mais

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    est plus claire que moi alors je reste sur un j'aime son post...
     
    MayBst apprécie ceci.
  • PhantomX

    PhantomX Member

    Inscrit:
    Juil 11, 2018
    Messages:
    78
    J'aime reçus:
    61

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Simplement que je préfère les tâches parallèles que je trouve beaucoup plus facile à gérer que les thread.

    Pour ma part, j'utilise des thread juste quand j'ai de besoin de boucle sans fin par exemple utilisation de socket ou quelque chose du genre.
    J'ai souvent eu des plantage lors d'utilisation de thread une fois l'application fermer, l'ordinateur devenant lent et je devais redémarré. Les threadsarrête ne sont pas recommendé par PcSoft et je ne suis pas trop sur de se que je doit réellement faire :p Ça me prendrait un cours approfondi sur les thread pour bien les utiliser.

    Les tâches parallèles sont plus faciles à utilisé à mon avis et c'est pour ça que je les conseils fortement car j'ai de beaucoup amélioré mes applications avec ceux-ci. (beaucoup plus fluide pour l'utilisateur)
    Dire que ma première utilisation d'une tâche parallèle à été fait car je voulais à tout pris mettre une image animé d'attente pour montrer qu'il y avait un traitement... lol, maintenant je les utilise partout surtout dans mes tableau de bord.
     
    MayBst apprécie ceci.
  • khaliassas

    khaliassas Active Member

    Inscrit:
    Mar 4, 2019
    Messages:
    446
    J'aime reçus:
    142

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Simplement que je préfère les tâches parallèles que je trouve beaucoup plus facile à gérer que les thread.

    Pour ma part, j'utilise des thread juste quand j'ai de besoin de boucle sans fin par exemple utilisation de socket ou quelque chose du genre.
    J'ai souvent eu des plantage lors d'utilisation de thread une fois l'application fermer, l'ordinateur devenant lent et je devais redémarré. Les threadsarrête ne sont pas recommendé par PcSoft et je ne suis pas trop sur de se que je doit réellement faire :p Ça me prendrait un cours approfondi sur les thread pour bien les utiliser.

    Les tâches parallèles sont plus faciles à utilisé à mon avis et c'est pour ça que je les conseils fortement car j'ai de beaucoup amélioré mes applications avec ceux-ci. (beaucoup plus fluide pour l'utilisateur)
    Dire que ma première utilisation d'une tâche parallèle à été fait car je voulais à tout pris mettre une image animé d'attente pour montrer qu'il y avait un traitement... lol, maintenant je les utilise partout surtout dans mes tableau de bord.
    Cliquez pour agrandir...
    Je comprenais je remarquais juste que tes explications sont plus claire que les miennes.
    Par contre tes précisions sont bienvenus car dans mes programmes je n'ai pas spécialement vu de différence et je le demandais ce qui étais le mieux.

    Pour moi c'était kiff kiff bourricot.
     
    MayBst apprécie ceci.
  • MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    tu peux aussi, à l'intérieur de ta procédure de ta tache parallèle utiliser :

    ExécuteThreadPrincipal(_ProcIHM)

    Ceci évite de lancer une TacheParalleleExecuteApres

    Tout dépend de tes besoins.
    Cliquez pour agrandir...
    Ca je l'ai fait dans une autre procédure, mais je n'étais pas très satisfaite. C'est pour ça que je me suis tournée vers les tâches parallèles.

    En tout cas merci encore pour ton aide !
     
  • MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Simplement que je préfère les tâches parallèles que je trouve beaucoup plus facile à gérer que les thread.

    Pour ma part, j'utilise des thread juste quand j'ai de besoin de boucle sans fin par exemple utilisation de socket ou quelque chose du genre.
    J'ai souvent eu des plantage lors d'utilisation de thread une fois l'application fermer, l'ordinateur devenant lent et je devais redémarré. Les threadsarrête ne sont pas recommendé par PcSoft et je ne suis pas trop sur de se que je doit réellement faire :p Ça me prendrait un cours approfondi sur les thread pour bien les utiliser.

    Les tâches parallèles sont plus faciles à utilisé à mon avis et c'est pour ça que je les conseils fortement car j'ai de beaucoup amélioré mes applications avec ceux-ci. (beaucoup plus fluide pour l'utilisateur)
    Dire que ma première utilisation d'une tâche parallèle à été fait car je voulais à tout pris mettre une image animé d'attente pour montrer qu'il y avait un traitement... lol, maintenant je les utilise partout surtout dans mes tableau de bord.
    Cliquez pour agrandir...
    Moi aussi j'ai ces problèmes avec les thread.

    Je serais bien intéressée par des exemple d'utilisation des tâches parallèles, si ça ne t'ennuie pas.
     
  • PhantomX

    PhantomX Member

    Inscrit:
    Juil 11, 2018
    Messages:
    78
    J'aime reçus:
    61

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Les cas principaux que j'utilise les tâches parallèles :

    Dans une application MRP :
    Tableau de bord en live pour afficher état des équipements, item en production de l’équipement, avancement de la production de chaque équipement, nombre de commande, statut des commandes, etc...
    J'ai aussi des widget pour chaque personnel de bureau pour indiquer des problème/anomalies exemple, lors d'une création de produit, si le produit manque certaine spécification que seul le service clientèle peut répondre, alors il a (les personnes ressources du services clientèles) un widget pour indiquer que quelqu'un à créer un nouveau produit et qu'il doit le complété. Ou un widget pour les personnes à l'expédition pour valider et envoyer à la facturation lorsqu'une commande est expédié. Bref, plutôt que de ce parler ou de recevoir des mails, je me sert du tableau de bord pour notifier les personnes ressources, (ceci permet d'afficher les widgets selon les besoins de chaque utilisateurs facilement).
    Tout ça est en live, je me sert du HSurveille() pour récupéré les modifications de certaines tables sur le serveur, et j'exécute mes traitement dans des taches parallèles pour ne pas bloquer l'interface, et j'affiche le résultat dans les widgets.

    Partout ou je veux une image animée pour montré qu'il y a un traitement.
    Code (Text):
    // Affichage de l'image
        IMG_Loading..visible = vrai

    // Lancement des tacheparlleles
    soit t = TacheParalleleExecute(_Traitement, (p1, p2), tpoCopieDifféréeContexteHFSQL)
    TacheParalleleExecuteApres(t, _ProcIHM, (), tpoThreadPrincipal)

    PROCÉDURE INTERNE _ProcIHM()
         IMG_Loading..visible = faux
    FIN
    Lors d'ouverture de fenêtre que je trouve trop longue à mon goût :
    J'exécute une tache parallèle qui récupère les données. Pendant ce temps, la fenêtre est affiché très rapidement car elle ne fait que "afficher" l'IHM et quand la tâche a récupérée les données, j'affiche les données dans la fenêtre. Ca évite un clique sur un bouton pour ouvrir la fenêtre et un délais d'attente que tu n'est plus sur que tu ton clique à bien fonctionner :p
    Quand c'est une table ou une ZR par exemple, plutôt que de mettre le contenu sur une requête, je met la liaison à un tableau de structure global à la fenêtre.

    Code (Windev):

    // Déclaration des globales de la fenêtre (ou du projet)
    stItem est une structure
        Id est un entier
        Nom est une chaine
        Stock est un entier
    FIN

    tItem est un tableau de stItem

    Procédure _LanceTraitement()
        soit t = TacheParalleleExecute(_RemplieLeTableauDeStructure, (p1, p2), tpoCopieDifféréeContexteHFSQL)
        TacheParalleleExecuteApres(t, _AfficheZR, (valeurrenvoyétacheprécédente), tpoThreadPrincipal)
    FIN

    Procédure _RemplieLeTableauDeStructure(p1, p2) : stItem
        MesItems est un tableau de stItem

        // Traitement pour remplir le tableau de structure
        ...

        RENVOYER MesItems
    FIN

    Procédure _ProcIHM(local ti est un tableau de stItem)
        tItem = ti
         ZR_Produits.Affiche()
    FIN
    Ceci améliore énormément la fluidité entre les fenêtres.

    Afficher en live des tables :
    J'utilise beaucoup le HSurveille pour mettre à jours en live les données via des requêtes.
    Exemple, une table qui affiche toute les commandes, je veux que la personne qui à le carnets de commandes à la vue soit rafraichit si quelqu'un d'autre entre une nouvelle commande. Si j'exécute une simple requête, ça bloc l'interface pendant un cours laps de temps. Si le serveur est sollicité, ça peut bloqué prêt de 1/2 secondes, ce qui est 1/2 secondes de trop à mon avis si on était en train de faire d'autre chose et que notre clique ne fonctionne plus.
    J'utilise donc le même principe que ma 3e exemple. Mon HSurveille() lance une Tache Parallèle, je modifie mon tableau de structure mémoire et ré affiche le carnets de commandes sans que l'utilisateur soit bloquer, voir même s'en aperçoive si je lui indique pas avec un toast ou quelque chose du genre.


    Traitements séquentielles :

    Exemple, l'utilisateur affiche certain item avec des filtres, tu les affiches dans une table dans la colonne A et tu doit donné un résultat de performance de production, rentabilité pour chaque item dans la colonne B.
    Plutôt que de parcourir ta table et de lancer ton traitement pour chaque item, ce qui 1) bloque l'interface et 2) est très long car le traitement de l'item 1 doit être terminé avant le traitement de l'item 2.
    A la place tu lance un tâche parallèle pour chaque item pour exécuter ton traitement (attention tu viens de monter ton serveur en charge par contre) mais le résultat est franchement plus rapide.


    ETC... :
    :p

    Quand on est sur un serveur distant, ceci prend encore plus de sens, ceci évite de bloquer les interfaces pendant la récupération des données.


    Ouin... je me suis encore laisser emporter, je vais finir par me faire bannir pour post trop long :p

    Espérant t'avoir donnée quelques idées ;)
     
  • khaliassas

    khaliassas Active Member

    Inscrit:
    Mar 4, 2019
    Messages:
    446
    J'aime reçus:
    142
    en tout cas super clair, :openedeyewink:
     
    PhantomX apprécie ceci.
  • Man

    Man Active Member

    Inscrit:
    Juil 9, 2018
    Messages:
    290
    J'aime reçus:
    67

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Les cas principaux que j'utilise les tâches parallèles :

    Dans une application MRP :
    Tableau de bord en live pour afficher état des équipements, item en production de l’équipement, avancement de la production de chaque équipement, nombre de commande, statut des commandes, etc...
    J'ai aussi des widget pour chaque personnel de bureau pour indiquer des problème/anomalies exemple, lors d'une création de produit, si le produit manque certaine spécification que seul le service clientèle peut répondre, alors il a (les personnes ressources du services clientèles) un widget pour indiquer que quelqu'un à créer un nouveau produit et qu'il doit le complété. Ou un widget pour les personnes à l'expédition pour valider et envoyer à la facturation lorsqu'une commande est expédié. Bref, plutôt que de ce parler ou de recevoir des mails, je me sert du tableau de bord pour notifier les personnes ressources, (ceci permet d'afficher les widgets selon les besoins de chaque utilisateurs facilement).
    Tout ça est en live, je me sert du HSurveille() pour récupéré les modifications de certaines tables sur le serveur, et j'exécute mes traitement dans des taches parallèles pour ne pas bloquer l'interface, et j'affiche le résultat dans les widgets.

    Partout ou je veux une image animée pour montré qu'il y a un traitement.
    Code (Text):
    // Affichage de l'image
        IMG_Loading..visible = vrai

    // Lancement des tacheparlleles
    soit t = TacheParalleleExecute(_Traitement, (p1, p2), tpoCopieDifféréeContexteHFSQL)
    TacheParalleleExecuteApres(t, _ProcIHM, (), tpoThreadPrincipal)

    PROCÉDURE INTERNE _ProcIHM()
         IMG_Loading..visible = faux
    FIN
    Lors d'ouverture de fenêtre que je trouve trop longue à mon goût :
    J'exécute une tache parallèle qui récupère les données. Pendant ce temps, la fenêtre est affiché très rapidement car elle ne fait que "afficher" l'IHM et quand la tâche a récupérée les données, j'affiche les données dans la fenêtre. Ca évite un clique sur un bouton pour ouvrir la fenêtre et un délais d'attente que tu n'est plus sur que tu ton clique à bien fonctionner :p
    Quand c'est une table ou une ZR par exemple, plutôt que de mettre le contenu sur une requête, je met la liaison à un tableau de structure global à la fenêtre.

    Code (Windev):

    // Déclaration des globales de la fenêtre (ou du projet)
    stItem est une structure
        Id est un entier
        Nom est une chaine
        Stock est un entier
    FIN

    tItem est un tableau de stItem

    Procédure _LanceTraitement()
        soit t = TacheParalleleExecute(_RemplieLeTableauDeStructure, (p1, p2), tpoCopieDifféréeContexteHFSQL)
        TacheParalleleExecuteApres(t, _AfficheZR, (valeurrenvoyétacheprécédente), tpoThreadPrincipal)
    FIN

    Procédure _RemplieLeTableauDeStructure(p1, p2) : stItem
        MesItems est un tableau de stItem

        // Traitement pour remplir le tableau de structure
        ...

        RENVOYER MesItems
    FIN

    Procédure _ProcIHM(local ti est un tableau de stItem)
        tItem = ti
         ZR_Produits.Affiche()
    FIN
    Ceci améliore énormément la fluidité entre les fenêtres.

    Afficher en live des tables :
    J'utilise beaucoup le HSurveille pour mettre à jours en live les données via des requêtes.
    Exemple, une table qui affiche toute les commandes, je veux que la personne qui à le carnets de commandes à la vue soit rafraichit si quelqu'un d'autre entre une nouvelle commande. Si j'exécute une simple requête, ça bloc l'interface pendant un cours laps de temps. Si le serveur est sollicité, ça peut bloqué prêt de 1/2 secondes, ce qui est 1/2 secondes de trop à mon avis si on était en train de faire d'autre chose et que notre clique ne fonctionne plus.
    J'utilise donc le même principe que ma 3e exemple. Mon HSurveille() lance une Tache Parallèle, je modifie mon tableau de structure mémoire et ré affiche le carnets de commandes sans que l'utilisateur soit bloquer, voir même s'en aperçoive si je lui indique pas avec un toast ou quelque chose du genre.


    Traitements séquentielles :

    Exemple, l'utilisateur affiche certain item avec des filtres, tu les affiches dans une table dans la colonne A et tu doit donné un résultat de performance de production, rentabilité pour chaque item dans la colonne B.
    Plutôt que de parcourir ta table et de lancer ton traitement pour chaque item, ce qui 1) bloque l'interface et 2) est très long car le traitement de l'item 1 doit être terminé avant le traitement de l'item 2.
    A la place tu lance un tâche parallèle pour chaque item pour exécuter ton traitement (attention tu viens de monter ton serveur en charge par contre) mais le résultat est franchement plus rapide.


    ETC... :
    :p

    Quand on est sur un serveur distant, ceci prend encore plus de sens, ceci évite de bloquer les interfaces pendant la récupération des données.


    Ouin... je me suis encore laisser emporter, je vais finir par me faire bannir pour post trop long :p

    Espérant t'avoir donnée quelques idées ;)
    Cliquez pour agrandir...
    Au contraire

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    ça prouve que vous maîtrisez votre chose. tes explications et quelques exemples m'ont amené à poser quelques questions.
    1. je veux afficher la liste des utilisateurs en utilisation une requête paramétrée. Pour se faire j'ai utilisé les structures que je ne maîtrise pas bien mais j'ai fais un bricole, et quand bien je le fais IHM se bloque jusqu'à la fin du processus le plus intéressante est que les données s'affichent en un seul fois.
    2. Si vous pouvez nous donner surtout les néophytes comme moi un tuto complet sur la manipulation des structures, des tâches parallèles en basant sur un exemple concret.
    Car à vous lire ça me donne le goût de vous suivre.
    merci.
     
    MayBst apprécie ceci.
  • MayBst

    MayBst Member

    Inscrit:
    Jan 10, 2019
    Messages:
    66
    J'aime reçus:
    15

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    merci pour ces exemples :eek:
    Je me demandais, pour le cas par exemple d'un tableau de bord en live, c'est un thread secondaire avec un timer que tu dois mettre en place non ?

    N'est-ce pas gênant pour les utilisateurs d'avoir une fenêtre vide à l'ouverture ? Même si elle se remplit quelques millisecondes après.

    Merci de m'avoir fait découvrir HSurveille que je ne connaissais pas du tout. Je vais me pencher dessus, tes exemples sont vraiment très instructifs.

    Merci pour ce long message :)
     
  • PhantomX

    PhantomX Member

    Inscrit:
    Juil 11, 2018
    Messages:
    78
    J'aime reçus:
    61

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    ceci n'est pas un tuto, mais ca va peut être t'aider à mieux comprendre comment on peut utilisé une structure :)

    Dans le code d'initialisation j'utilise une procédure pour remplir la fenêtre et je réutilise la même procédure dans mon HSurveille() (ou plutôt une légère variante)

    Ceci est un exemple pour afficher le nombre de commandes actives et le nombre de commandes en retards dans un widget dans une tableau de bord:


    *****IHM Fenêtre interne*****
    Dans une fenêtre interne que tu prends soins de mettre dans ton Tableau de bord
    Mettre 2 gros libellés en format numérique (ou boutons si tu veux que ce soit interactif, le SourceVersEcran ne pourra plus fonctionner, par contre tu devra plutôt mettre BTN_CmdActive..libellé = NbrCommandePourIHM .NbrCmdActive ...)
    - Un avec une liaison fichier sur ta structure NbrCommandePourIHM .NbrCmdActive
    - Un avec une liaison fichier sur ta structure NbrCommandePourIHM .NbrCmdEnRetard



    *****Code d'initialisation de ma fenêtre interne*****

    // Si tu as à utiliser ta structure plusieurs fois dans ton projets, met là dans l'initialisation du projet à la place
    stNbrCommandesOuverte est une structure
    NbrCmdActive est un entier
    NbrCmdEnRetard est un entier
    FIN

    NbrCommandePourIHM est un stNbrCommandesOuverte <section critique> // Ne pas oublier le <section critique> pour être sur que 2 tâches parallèles ne puisse pas accéder à NbrCmd en même temps et créer un conflit

    HSurveille(Commandes, _ChargeEtAfficheNombreDeCommandes_Surveille, hNumEnrTous, hsAjout+hsModification+hsRaye+hsSuppression)



    *****Code de fin d'initialisation*****
    _ChargeEtAfficheNombreDeCommandes() // Tout simplement



    *****Procédure 1*****
    Procédure _ChargeEtAfficheNombreDeCommandes()

    soit t = TacheParallelesExecute(_ChargeDonnees, (p1, p2))
    TacheParalleleExecuteApres(t, _AfficheDonnes, (ValeurRetournerTachePrecedente), tpoThreadPrincipal)

    Procédure interne _ChargeDonnees() : stNbrCommandesOuvertes // les : après la procédure force le type de variables retourné par la procédure, le compilateur nous indique des erreurs si on utilise pas le bon type (très pratique pour éviter des erreurs, j'ai pensé que ce pourrait être utile pour certain car ça fait pas longtemps que je connais cette fonctionnalité alors je me doute que je ne suis pas le seul :p)

    // Structure qui va contenir le résultat que je veux afficher
    NbrCmdREQ est un stNbrCommandesOuvertes

    // exécution de la requête pour récupérer le nombre de commandes actives (cette procédure s'exécute dans une tâches parallèles donc la requête est non bloquante)
    HExecuteRequete(REQ_RecupCommandesOuverteEtRetard)
    HlitPremier(REQ_RecupCommandesOuverteEtRetard)

    // passage en variables du résultat de la requête pour pouvoir simplifier le transfert vers la procédure qui touche le ThreadPrincipal

    NbrCmdREQ.NbrCmdActive = REQ_RecupCommandesOuverteEtRetard.Count_CmdActive
    NbrCmdREQ.NbrCmdEnRetard = REQ_RecupCommandesOuverteEtRetard.Count_CmdRetard

    // Libération de la requête sur le serveur, on en a plus besoin on passé le résultat à la structure

    HLibereRequete(REQ_RecupCommandesOuverteEtRetard)

    RENVOYER NbrCmdREQ
    FIN

    Procédure interne _AfficheDonnees(Local NbrCmd est un structure)
    // Cette procédure touche l'interface, donc est bloquante, elle se doit d'être la plus courte possible, ne pas accéder au données, requête et / ou faire des calculs car cela pourrait impacter sur l'IHM

    // Donne le résultat récupéré à la variable globale de la fenêtre pour utiliser SourceVersEcran
    NbrCommandePourIHM = NbrCmd

    // Ceci met à jour l'IHM car nous avons pris soin de lier nos libellés de notre widget (fenêtre interne) avec la variable de la structure
    SourceVersEcran(MaFenetreInterne, NbrCommandePourIHM)
    FIN



    *****Procédure HSurveille*****
    Procédure _ChargeEtAfficheNombreDeCommandes_Surveille(sd est une source de données, enr est un enregistrement)
    // Exemple ici d'une application qui gère plusieurs société, on veut exécuter la procédure seulement si la société est celle qu'on est configuré

    // sd est en réalité notre Fichier Commandes car le HSurveilles prend en paramètre le fichier Commandes, donc il récupère la commandes qui vient d'être modifié
    // Si tu veux vraiment optimiser, le HLit devrait aussi être en tâche parallèle pour éviter un blocage d'IHM si la récupération des données serait vraiment lente, mais bon, pour l'exemple je l'ai pas fait :p

    HLit(sd, enr)

    // on fait un retour si la commande qui vient d'être ajouter ou modifié n'appartient pas à la société auquel on est connecter, ceci évite d'exécuter la procédure inutilement, juste un mini aller retour pour valider plutôt que d'exécuter une requête (ceci est pour l'exemple bien sur à vous de faire selon vos besoins et le vouloir d'optimiser)

    Si sd.IdSociete <> MonIdSocieteConnecter alors Retour

    // on lance la même procédure qu'à la fin de l'initialisation de la fenêtre interne
    _ChargeEtAfficheNombreDeCommandes()

    FIN

    *****Pour finir dans tout ça*****
    On s'entend que c'est relativement plus long à coder qu'une requête basé sur un timer mais ça en vaut vraiment la peine.

    Fait un copier coller du code pour mieux voir le code
    Bien entendu, essayer de déchiffrer le code et de le comprendre avant de continuer à l'utiliser dans vos projets :p

    Alors si tu modifie une commande la procédure de ton HSurveille ce lancera et s’exécutera automatiquement en tâche parallèle.
    Ton résultat est récupéré sans blocage et est ensuite envoyé à l'IHM
    Bon je sais qu'avec de la POO ce serait encore mieux, mais je m'y suis pas encore mit alors... pour l'instant ça fait le travail :)

    Si tu as à utiliser la même fenêtre interne plusieurs fois dans ton tableau de bord, n'oublie pas de coché "Contexte HFSQL indépendant" pour éviter que tout se mélange.

    P.S. Le code à été écrit à la volé et non tester alors s'il y a des petites choses en le testant, faite moi signe que je l'édite :)
     
    Man et suenodesign aiment ça.
  • PhantomX

    PhantomX Member

    Inscrit:
    Juil 11, 2018
    Messages:
    78
    J'aime reçus:
    61

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    N'est-ce pas gênant pour les utilisateurs d'avoir une fenêtre vide à l'ouverture ? Même si elle se remplit quelques millisecondes après.

    Perso j'aime mieux voir un tableau de bord au démarrage avec des champs vide avec une jauge animé dans chaque fenêtre le temps que les données s'affiche plutôt que d'avoir une application qui se lance en 20 seconde car c'est ce que prendrait une de met application qui à une 30aine de widget. (J'ai oublier dans mon exemple plus haut d'afficher et de rendre invisible une jauge animé dans le Procédure affectant l'IHM )
    Tant que l'utilise vois qu'il y a du travail qui s'effectue pour ne pas qu'il doute des données affichés.
     
  • Partager cette page

    Chargement...