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

Langage Delphi Discussion :

Initialisation Programme et unité


Sujet :

Langage Delphi

  1. #1
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    760
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 760
    Points : 499
    Points
    499
    Par défaut Initialisation Programme et unité
    Bonjour,

    Désolé pour ce titre confus, je n'avais pas d'idée plus précise.

    Os W10 et delphi Rio.

    Ci-dessous quand je parle d'initialisation d'unités, il s'agit de code qui se trouve entre le dernier bloc "begin..end." de cette unité.

    j'ai une application, dans lequel on trouve dans le programme principal (*.dpr) et dans l'ordre décris ci-dessous :
    • Des "Mutex", pour éviter d'exécuter plusieurs instances de la même application et/ou des instances d'applications interdites ou qui ne peuvent cohabiter en même temps.
    • Un splash (fenêtre d’accueil), pour faire patienter l'utilisateur le temps :
    • d'executer divers actions.
    • Que les créations des fiches actives soient finalisées environ 6 sur les 70.
    • diverses actions ...


    Cette tache dure environs 30 secondes, cela remplissait le job, mais avec le temps nous avons ajoutés diverses opérations dans les "initialisations" des diverses unités, qui sont executées dans l'exécution des uses. Cela implique que rien ne se passe (visuellement pendant quelques secondes) entre le lancement de l'application et la création des "Mutex" et de l'affichage du splash.

    A ce jour, ces initialisations peuvent prendre quelques secondes (cette durée étant en fonction des Pc). Vus l'absence d'information, l'utilisateur pense avoir raté son double-clic sur l’icône du raccourci de l'application et reclique plusieurs fois avant que le "Mutex" ne l'interdise et donc lance plusieurs instances de l'application. Cela peut provoquer des exceptions quand plusieurs instances se lancent en même temps.

    Mes idées pour indiquer à l'utilisateur que l'application est en train de se charger sont:

    - 1° Changer le type de curseur, mais à l'endroit ou je souhaiterai le faire, l'application c'est pas encore lancée donc cela ne devrait pas fonctionner. Puis-je changer depuis delphi le curseur de Windows ?

    - 2° Déplacer les "Mutex" dans l'initialisation de la 1er unité exécutée. Dans tous les exemples que j'ai vus, cette action est dans le DPR, et mes premiers essais sur ce déplacement ne semblent pas concluant. Est il possible de déclarer et gérer ces "Mutex" ailleurs que dans le *.DPR ?.


    Merci de votre aide.

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    Les mutex peuvent être créés à n'importe qu'elle moment. Qu'entends-tu par pas concluant ?

    La première unité listée dans le dpr ne signifie pas que son bloc d'initialisation sera exécuté en premier. Il ne le sera que lorsque ceux de ces propres uses (et récursivement) l'auront été. Il faudrait une unité dédiée avec le minimum de dépendances pour que la création des mutex soit la plus rapide possible.

    Après si les blocs d'initialisation prennent tant de temps, il y a peut-être un concept à revoir. Par exemple déplacer certaines choses dans des constructeurs de classe (class constructor) qui ne seront exécutés qu'à la première instanciation plutôt qu'au lancement du programme.

  3. #3
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 444
    Points : 5 864
    Points
    5 864
    Par défaut
    salut


    dans ton DPR tu ne doit pas créer toutes tes form (ce que fait delphi par défaut)
    a toi de gérer la création et la destruction de celle-ci

    Ps : pour le cursor c'est simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     Screen.Cursor := crHourGlass;
    ...
     Screen.Cursor:= crDefault;

  4. #4
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    760
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 760
    Points : 499
    Points
    499
    Par défaut
    bonsoir a vous deux !

    Andnotor:
    En ce qui concerne le concept, on est d'accord! mais cela a été une solution provisoire qui est devenue permanente et à force de l'utiliser ... on a ce problème.

    Oui, ce n'est pas la 1er unité listée du DPR qui est exécutée en 1er, je l'ai trouvé en mettant des points d'arrêts dans les initialisations, en fait sur la 100ene d'unités que j'utilise, seules 5 ou 6 on des "initialisations" et une seule, la 1er utilisée devrait prendre du temps.
    Quand j’exécute chacun de ces blocs d'initialisations (avec un points d'arrêt en début et en fin de bloc) bizarrement je n'ai pas l'impression que les cumuls de ces durées soit le temps qu'il y a entre le lancement de l'application et le début du DPR. Mais bon c'est qu'une impression, peut-être que je mettrai un compteur pour être sur !

    Pour le "Mutex", je ne sais pas comment l'utiliser plus tôt que dans le début du programme principal (le Dpr).
    Ma manip était idiote car j'utilise un Mutex dans mon initialisation, pour définir l'état d'un booléen qui autorise ou pas le déroulement du programme.., et ou se trouve ce booléen... au début du programme principal, donc pas d'amélioration .

    Anapurna:
    Pour les fiches oui, sur les 78 forms qui existent seule une 10ene sont crées automatiquement, toutes les sont disponibles et crées quand j'en ai besoin.

    Pour le curseur, je fait comme toi en général, mais cette fois dans l’initialisation de la fameuse unité donc je parle ci-dessus.
    Cette unité n'a pas de fiche associée, j'ai déclarée quand même l'unité "Forms", et il me dit qu' il ne connait pas la méthode "screen.cursor" qui est bien déclarer dans forms.
    En fait c'est plus la lecture de toutes les dépendances dans le uses qui prends du temps que les create des fiches.

    En écrivant ceci, il me vient une idée, puis-je avoir de la redondance dans les déclarations de uses de diverses unités (pas de la même ou cela génère une erreur).
    Car nous avons ajouté dans une unité (A) qui est déclarée dans toutes les autres, deux autres unités (B et C) qui elles ne sont pas utilisées par tout le monde.
    Mais cette manip nous à imposée de rajouter les unités (B et C) a toutes celles qui utilise l'unité (A) soit presque toutes même si elle n'en ont pas besoin.
    Ce genre de manip peut augmenter aussi la lecture des dépendances de chaque .pas ! et donc aussi le temps pour atteindre le début du DPR.

    Tant que nous y sommes existe t il un outils pour nettoyer les uses...?

    Merci à vous deux, je vais me remettre sur ce problème.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 15
    Points : 15
    Points
    15
    Par défaut
    Bonsoir

    Est-ce qu’en lançant certains des traitements de la phase d’initialisation dans plusieurs thread ne permettrait-il pas d’accélérer le lancement de ton applicatif ?
    Mais je pense que tu as déjà tenté cette approche…

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    Citation Envoyé par petitcoucou31 Voir le message
    Pour le "Mutex", je ne sais pas comment l'utiliser plus tôt que dans le début du programme principal (le Dpr).
    Tu crées une unité minimaliste :
    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
    unit AppMutex;
     
    interface
     
    uses WinApi.Windows;
     
    implementation
     
    const MutexName = 'MyAppMutex';
     
    initialization
      if OpenMutex(MUTEX_ALL_ACCESS, TRUE, MutexName) = 0
      then CreateMutex(nil, TRUE, MutexName)
      else Halt(0);
     
    end.
    et la place en début de liste :
    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
    program Project1;
     
    uses
      AppMutex in 'AppMutex.pas',  // <-------- 
      Vcl.Forms,
      Main in 'Main.pas' {fMain};
     
    {$R *.res}
     
    begin
      Application.Initialize;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TfMain, fMain);
      Application.Run;
    end.
    C'est tout !

  7. #7
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 614
    Points
    3 614
    Par défaut
    Tout ce qui peut être fait dans des tâches doit l'être pour alléger au maximum l'interface utilisateur et le thread principal, mais gaffe à ne pas compliquer les choses ou générer des conflits imprévus.

    L'intérêt des blocs initialization c'est de pouvoir maîtriser l'ordre d'exécution des choses au démarrage du programme. Pas sûr que des threads y aient vraiment leur place, mais pourquoi pas tant que les unités utilisant celle-ci n'aient pas besoin d'utiliser ce qu'elle contient dans leur propre initialization.

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    alors l'initialization de la première unité du DPR se fait en premier seulement si elle n'utilise pas elle-même d'autres unités, car dans ce cas c'est l'initialization de la première unité de sa clause uses qui est appelé avant (et ce de façon récursive) jusqu'à tomber sur une unité qui soit n'a pas de uses, soit n'utilise que des unités sans code d'initialisation...et là on a le premier code exécuté. La RTL a elle même un certain nombre de code d'initialisation qu'on peut laisser se faire en général...sauf par exemple si on veux remplacer le gestionnaire de mémoire => FastMM ou ShareMem en premier !

    le code begin/end du DPR s'exécute quand à lui à la fin de l'initialisation de toutes les unités.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 15
    Points : 15
    Points
    15
    Par défaut
    J’ai déjà été confronté à ce problème, pour le résoudre j’avais signé chaque phase d’initialisation avec un GetTickCount et un message concernant l’unité afin de retrouver l’ordre d’initialisation et également d’évaluer les phases chronophages et d’isoler les parties de codes n’ayant pas d’influence sur le bon déroulement de l’initialisation... j'avoue que cela a pris un peu de temps mais le jeu en valait la chandelle

  10. #10
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 759
    Points : 5 482
    Points
    5 482
    Par défaut
    Citation Envoyé par petitcoucou31 Voir le message
    Tant que nous y sommes existe t il un outils pour nettoyer les uses...?.
    CnPack contient, entre autres choses, un outil pour nettoyer les uses.

  11. #11
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    760
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 760
    Points : 499
    Points
    499
    Par défaut
    Bonsoir et merci à vous tous.

    Après la lecture de certains fils et le rappel que les codes non utilisés ne sont pas compilés, le nettoyage des Uses ne semble intéressant que pour meilleure lisibilité du code par autrui ou pour plus tard. Du moins cela ne semble pas être lié à ce post.

    J'ai utilisé la méthode de AndNotOr, sans en connaitre la raison je ne pensais pas qu'il était possible de mettre du code à cet endroit là et bien sûr cela fonctionne bien..., plus de lancements multiples de l'application.

    J'en ai aussi profiter pour mettre dans cette unité très minimaliste, une form qui affiche un logo... quelques secondes le temps que le véritable Splash s'affiche et ne laisse plus l'utilisateur dans le doute de savoir si l'application est ou pas lancé, problème récurent quand on est mode tactile.

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

Discussions similaires

  1. [Python 3.X] RE-initialisation programme (redemarrage)
    Par danardui dans le forum Général Python
    Réponses: 4
    Dernier message: 02/02/2018, 12h30
  2. initialisation programme multilangue
    Par holdup37 dans le forum C++Builder
    Réponses: 1
    Dernier message: 09/05/2007, 16h06
  3. Réponses: 2
    Dernier message: 30/01/2007, 18h04
  4. Programmation par unités multiples
    Par Mimi Bulles dans le forum Langage
    Réponses: 6
    Dernier message: 09/06/2005, 23h08

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