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 :

E2555 Impossible de capturer le symbole


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut E2555 Impossible de capturer le symbole
    Bonjour,

    Je cherche le moyen de résoudre "élégamment" cette erreur :
    Y a t il un moyen de laisser Createcontrols dans la procedure InternalAdImage ou la seule solution est de la mettre en méthode de la classe TFrameShowOperations (ce qui m'oblige à renvoyer les controles créés) ?

    il y a une erreur de compilation sur le deuxième appel de Createcontrols : E2555 Impossible de capturer le symbole 'CreateControls'

    delphi 10.4.2
    fmx

    Merci

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
     
    procedure TFrameShowOperations.InternalAddImage (aItem : TFrameLayoutOperation);
    var
      img : TImage;
      lbl : TLabel;
     
    procedure CreateControls (aParent : TFMXObject);
      begin
    // create controls
       img := TImage.create (aParent);
      lbl := TLabel.create (aParent);
    ...
     
      end;
     
     
    begin
        if TFile.Exists (s) then
           begin
             CreateControls (aItem.LayoutGallery);
             lbl.text := 'gggg';
             img.Bitmap.LoadFromFile (s);
     
           end
         else
           begin
             AsyncAwait(
             procedure ()
             begin
     // load image
     
             end,
             procedure ()
             begin
               synchronizeForm (
               procedure ()
               begin
                      CreateControls (aItem.LayoutGallery); // E2555 Impossible de capturer le symbole 'CreateControls'
     
                      lbl.text := 'gggg';
                      img.Bitmap.LoadFromFile (s);
     
                    end;
               end);
     
             end);
     
           end;
      end;
    end;

  2. #2
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    mars 2006
    Messages
    1 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : mars 2006
    Messages : 1 356
    Points : 2 549
    Points
    2 549
    Billets dans le blog
    10
    Par défaut
    En dehors de l'erreur signalée il y a confusion entre Owner et Parent.
    SI tu nous donnes une version plus complète on pourra te donner la solution.
    Note : a priori tu ne viens pas du monde Delphi

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 001
    Points : 21 055
    Points
    21 055
    Par défaut
    Tiens, j'ai eu cette erreur aussi pour un type trop complexe en XE2, curieusement, j'ai eu moins de soucis en D10 (même si j'ai réduit au plus que possible l'utilisation du Synchronize)

    déclare une variable locale pour stocker aItem.LayoutGallery et ulilise cette variable dans la méthode synchronizée, comme tu as des imbrications, cela complique surement

    Voici un exemple dans un code fonctionnel et en production depuis plusieurs années, je te laisse l'adapter à ta situation ... mais c'est beaucoup ce montage AsyncAwait \ SynchronizeForm, est-ce vraiment utile de faire cela ?

    Et pour CreateControls, faut la sortir, lui donner une visibilité plus large (ou voir si tu peux l'imbriquer dans AsyncAwait )

    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
    18
    19
    20
    //------------------------------------------------------------------------------
    class procedure TModuleLogistiqueAutomateMonitor.RemoteMessageWaveChangeStateEventHandler(AOrigin: TxxxxModuleAutomateLogistique.TRemoteMessageSocketHandle; const AEvent: TxxxxModuleAutomateLogistique.TRemoteMessageEvent);
    var
      SynchronizedEvent: TxxxxModuleAutomateLogistique.TRemoteMessageEvent;
    begin
      SynchronizedEvent := AEvent; // Stockage du paramètre dans une variable locale
     
      TrySynchronize(
        procedure
        begin
          if not Application.Terminated then
          begin
            if SynchronizedEvent.EventType = rmetWaveInducting then
              TxxxxSingleton<TModuleLogistiqueAutomateMonitor>.Instance.AddMessage(Format('Contenant %d à induire ', [SynchronizedEvent.InductingWaveID]))
            else if SynchronizedEvent.EventType = rmetWaveInducted then
              TxxxxSingleton<TModuleLogistiqueAutomateMonitor>.Instance.AddMessage(Format('Contenant %d induit', [SynchronizedEvent.InductedWaveID]));
          end;
        end
      );
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 983
    Points : 25 873
    Points
    25 873
    Par défaut
    à priori il suffit de sortir CreateControls de TFrameShowOperations.InternalAddImage pour en faire une procédure globale

    ou alors en faire une méthode anonyme.

    mais ce n'est clairement pas un code Delphi habituel
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 001
    Points : 21 055
    Points
    21 055
    Par défaut
    En fait, c'est une variante d'un exemple Embarcadero : Tutoriel : Utilisation des tâches de la bibliothèque de programmation parallèle avec TTask.Run et TThread.Synchronize qui ressemble à AsyncAwait et SynchronizeForm

    Il semble que cela de plus en plus à la mode ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 983
    Points : 25 873
    Points
    25 873
    Par défaut
    oui tu as ça en C# et Javascript par exemple...et donc sous Delphi aussi maintenant
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 001
    Points : 21 055
    Points
    21 055
    Par défaut
    Je suppose qu'en FMX sur un mobile, bloquer l'IHM ne se pratique pas comme sous Windows où l'on ferait juste une fenêtre de patience.

    Si la correction de la portée de CreateControls en méthode privée de TFrameShowOperations semble évidente effectivement

    Une construction asynchrone est-elle vraiment nécessaire ?
    à part l'absence d'une image locale et le besoin de télécharger l'image depuis un serveur par exemple, tout ça semble tellement complexe pour peu de chose.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Je suppose qu'en FMX sur un mobile, bloquer l'IHM ne se pratique pas comme sous Windows où l'on ferait juste une fenêtre de patience.

    Si la correction de la portée de CreateControls en méthode privée de TFrameShowOperations semble évidente effectivement

    Une construction asynchrone est-elle vraiment nécessaire ?
    à part l'absence d'une image locale et le besoin de télécharger l'image depuis un serveur par exemple, tout ça semble tellement complexe pour peu de chose.

    J'ai sorti la procedure CreateControls avec des paramètres var pour renvoyer les controles créés

    C'est du delphi pur (dev delphi depuis v1 !)

    Sur mobile pour ne pas bloquer l'interface (et avoir un message android parce que le thread principal est bloqué) en attendant la fin du téléchargement des images depuis un serveur c'est très efficace et responsive
    On peut télécharger les images les afficher dans un timage et redimensionner le timage en fonction de la taille des images reçues depuis un thread asynchrone

    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
    18
    19
    20
    21
    22
    23
    24
    25
     
    procedure AsyncAwait(async, await: TProc);
    begin
      TThread.CreateAnonymousThread(
        procedure
        begin
          async();
     
          TThread.Queue(nil,
            procedure
            begin
              await();
            end
          ); // TThread.Queue
        end
      ).Start;
    end;
     
    procedure SynchronizeForm(const ARunProc: TThreadProcedure);
    begin
      if not IsMainThread then
        TThread.Synchronize(nil, ARunProc)
      else
        ARunProc;
    end;

  9. #9
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    mars 2006
    Messages
    1 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : mars 2006
    Messages : 1 356
    Points : 2 549
    Points
    2 549
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    oui tu as ça en C# et Javascript par exemple...et donc sous Delphi aussi maintenant
    A voir l'utilité réelle avec Delphi ... Je suis actuellement sur un gros projet de ce type (+5 500 000 lignes) et beaucoup de code sert à gérer ce qui existe en standard avec Delphi

  10. #10
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par ALWEBER Voir le message
    A voir l'utilité réelle avec Delphi ... Je suis actuellement sur un gros projet de ce type (+5 500 000 lignes) et beaucoup de code sert à gérer ce qui existe en standard avec Delphi
    J'ai essayé toutes sortes d'approches dont le classique écran d'attente d'un téléchargement qui peut être long en fonction de la qualité de ligne. C'est à la fois pas simple et bloquant pour le thread principal, ce qui est un défaut avec une application mobile.

    La méthode retenue est utilisée en Delphi dans diverses librairies delphi (https://github.com/DelphiWorlds/KastriFree) et permet de gérer les process asynchrones dans des threads séparés tout en permettant une interaction avec l'interface.

    C'est plutôt facile à écrire (en dehors de subtilité comme celle provoquant l'erreur de compilation) et le code est clair (de mon point de vue).

    Pour des applications mobiles en interactions avec serveur, cela me semble une approche indispensable car dans la philosophie des sdk sous jacents qui imposent les process.

  11. #11
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    mars 2006
    Messages
    1 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : mars 2006
    Messages : 1 356
    Points : 2 549
    Points
    2 549
    Billets dans le blog
    10
    Par défaut
    J'ai donné un cours il y a deux ou trois ans sur le sujet. Je vais essayer de retrouver l'exemple qui se rapproche de ta problématique

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 983
    Points : 25 873
    Points
    25 873
    Par défaut
    Citation Envoyé par hector94 Voir le message
    J'ai essayé toutes sortes d'approches dont le classique écran d'attente d'un téléchargement qui peut être long en fonction de la qualité de ligne. C'est à la fois pas simple et bloquant pour le thread principal, ce qui est un défaut avec une application mobile.

    La méthode retenue est utilisée en Delphi dans diverses librairies delphi (https://github.com/DelphiWorlds/KastriFree) et permet de gérer les process asynchrones dans des threads séparés tout en permettant une interaction avec l'interface.

    C'est plutôt facile à écrire (en dehors de subtilité comme celle provoquant l'erreur de compilation) et le code est clair (de mon point de vue).

    Pour des applications mobiles en interactions avec serveur, cela me semble une approche indispensable car dans la philosophie des sdk sous jacents qui imposent les process.
    c'est une question de philosophie, tu peux très bien faire du FMX sur portable avec la même philosophie que sous VCL en Delphi 1, l'écriture du code est juste différente

    pour ton cas, j'aurais tendance à créer le TImage dans tous les cas, si l'image existe en locale, je la charge, sinon je charge une image générique disponible en ressource par exemple, et je lance un Thread qui télécharge l'image et déclenche un évènement quand il a terminé pour charger l'image dans le TImage existant.

    tu peux découpler les chose si le TImage a des chances d'être détruit avant la fin du téléchargement...et là encore j'aime bien faire des choses simples

    1) placer le TImage dans un TList des images en attente de thread
    2) lancer le Thread avec un lien vers le TImage
    3) si le TImage est détruit, le supprimer de la liste des images en attente de thread
    4) quand le thread se termine, vérifier que l'image est toujours dans la liste (sinon c'est qu'il a été détruit et que son pointer local est invalide)
    5) supprimer le TImage de la TList si elle y était encore

    on peut aussi imager interrompre le thread à la destruction de l'image, mais en vrai ça rend les choses plus complexes

    et pour simplifier les choses, il ne faut pas hésiter à dériver les classes

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    type
      TAsyncImage = class(TImage)
       private
         FThread: TThread;
       public
         destructor Destroy; override; // ASyncList.Remove(Self);
         ...
      end;
     
      TAsyncDownload = class(TThread)
       FTarget: TAsyncImage;
        procedure Done; // à faire en Synchronize 
       ...
      end;
     
    var
      AsyncList: TList;
     
    procedure TAsyncDownload.Done;
    begin
      if AsyncList.IndexOf(FTarget) < 0 then // l'image n'existe plus
        Exit;
      FTarget.FThread := nil; // si on veux interrompre le Thread sur le destroy on indique ici qu'il est déjà terminé
      ...
    end;

    c'est plus verbeux, mais qu'est-ce que c'est plus facile à lire !!!
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 001
    Points : 21 055
    Points
    21 055
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    et pour simplifier les choses, il ne faut pas hésiter à dériver les classes
    Je ne peux pas fournir une classe ici d'un TImageWeb que j'ai car il n'est pas de moi mais c'est un héritage de TImage composé d'un TImageWebThread encapsulant un TIdHTTP
    L'idée étant de télécharger une image produit (vignette puis sur un clic, la version HD)
    une bonne partie du code a été réalisé en D5 et la gestion de GDI+ ajoutée en XE2, l'avantage le composant peut être utilisé n'importe où, il se comporte toujours en mode asynchrone, cela évite de devoir monter toutes ces méthodes anonymes à chaque fois.
    Toujours penser code réutilisable

    C'est assez similaire à la proposition de Paul Toth, hormis que le TImage invoque le TImageWebThread, si l'utilisateur ouvre la fiche produit (ou la fenêtre HD) et la ferme avant d'avoir eu le temps de télécharger l'image, le Destroy du TImage contenant un WaitFor, ainsi le Thread n'aura pas de risque d'avoir un TImage libéré en cours de route, le ThreadDone voyant un état Destroying écoutera son travail d'ailleurs.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  14. #14
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut
    Bonjour,

    Merci pour les propositions et explications

    Async/await fait parti de design pattern très couramment utilisé avec aisance par les dev react, node.js et autres.

    J'utilise plus logiquement :
    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
    18
    19
    20
    21
    22
    23
    24
    25
     
    procedure aSyncAwait(const ASyncProc: TThreadProcedure; const AWaitProc: TThreadProcedure = nil);
    begin
      TThread.CreateAnonymousThread(
        procedure
        begin
          ASyncProc;
     
         if Assigned(AWaitProc) then
            TThread.Synchronize(nil, AWaitProc);
        end
      ).Start;
    end;
     
    asyncawait (
    procedure
    begin
      // chargement ou calcul long
     
    end,
    procedure
    begin
    //affichage des résultats dans l'interface
     
    end);
    ce qui permet d'écrire un code clair et structuré.

    On peut évidement faire autrement et le faire directement dans un thread :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
      TThread.CreateAnonymousThread(
        procedure
        begin
          // chargement ou calcul long
     
            TThread.Synchronize(nil, 
               procedure
               begin
                 // affichage des résultats dans l'interface
     
              end);
        end
      ).Start;
    On peut le faire également en héritant une class TThread comme le propose Paul TOTH et ShaiLeTroll (ce que j'ai fait pendant longtemps...)

    Ce que je fais, comme d'autres, en utilisant ces design pattern , c'est aussi de voir et montrer qu'il est possible de coder en delphi avec des méthodes qu'un grand nombre de développeurs nouvellement formés ont acquises et utilises tous les jours avec automatisme.

    Peut-être un moyen d'attirer des dev vers delphi en proposant une autre image qu'un langage poo ou il faut créer des classes et des héritages qui donne l'impression d'une programmation delphi verbeuse et laborieuse.

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 983
    Points : 25 873
    Points
    25 873
    Par défaut
    <<OK Boomer>>

    certains poussent dans ton sens, et réclament les méthodes flèches sous Delphi par exemple.

    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
    18
    19
    20
    21
     
    procedure aSyncAwait(const ASyncProc: TThreadProcedure; const AWaitProc: TThreadProcedure = nil);
    begin
      TThread.CreateAnonymousThread(() => 
        begin
          ASyncProc;
     
         if Assigned(AWaitProc) then
            TThread.Synchronize(nil, AWaitProc);
        end
      ).Start;
    end;
     
    asyncawait (() =>
      // chargement ou calcul long
     begin
    end,
    () =>
    begin
    //affichage des résultats dans l'interface
    end);
    mais il faut bien voir que ce qui existe dans le monde javascript car au départ il est impossible de créer des thread, tout était fait par callback ce qui rendait le code parfois complexe, et donc async/await permet d'habiller des callback en méthodes pseudo séquentielles...alors que sous Delphi tu peux simplement placer ton code séquentiel dans un thread.

    après je ne suis pas contre des simplifications d'écriture (cf ici), mais je ne suis pas forcément pour une adoption des paradigmes d'autres langages qui ont leur raison d'être mais qui ne sont pas forcément nécessaire sous Delphi.

    Après ça existe, mais il faut savoir aussi le coût des captures, je sais bien que c'est aussi un comportement "OK Boomer" de se préoccuper de la charge machine, mais rien n'est gratuit en programmation
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 001
    Points : 21 055
    Points
    21 055
    Par défaut
    Citation Envoyé par hector94 Voir le message
    On peut évidement faire autrement et le faire directement dans un thread :
    Je ne vois pas la différence entre les deux versions, tout cela passe par les anonymes, c'est juste l'exemple que j'ai cité plus haut Tutoriel : Utilisation des tâches de la bibliothèque de programmation parallèle

    Cependant, attention à l'indentation, votre premier code était très mal écrit à ce sujet, donc difficile à lire



    Citation Envoyé par hector94 Voir le message
    Peut-être un moyen d'attirer des dev vers delphi en proposant une autre image qu'un langage poo ou il faut créer des classes et des héritages qui donne l'impression d'une programmation delphi verbeuse et laborieuse.
    Pascal est un langage de programmation impératif qui, conçu pour l'enseignement, se caractérise par une syntaxe claire, rigoureuse et facilitant la structuration des programmes.
    Première ligne du wikipedia
    Il faut savoir profiter des nouvelles syntaxes sans renier les anciennes

    Pourquoi opposer les méthodes ?
    Au lieu de répéter le Async\Await plusieurs fois dans le code, suffit juste de l'encapsuler dans une classe réutilisable
    Cela n'a rien de laborieux, c'est même un plaisir d'avoir un code d'utilisation simple pour masquer un fonctionnement complexe



    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
    18
    19
    procedure TFrameShowOperations.InternalAddImage (aItem : TFrameLayoutOperation);
     
      procedure CreateControls (aParent : TFMXObject; const AImageFileName: string);
      var
        img : TImageWeb;
        lbl : TLabel;
      begin
        img := TImageWeb.create (aParent);
        lbl := TLabel.create (aParent);
        ...
     
        img.OnLoad := CreateControlsLoadedEventHandler; // ça c'est ... lbl.text := 'gggg'; 
        img.FileName:= AImageFileName;
      end;
     
     
    begin
       CreateControls (aItem.LayoutGallery, s); 
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
      TImageWeb = class(TImage)
      private
        FFileName: string;
        FOnLoad: TNotifyEvent;
        procedure SetFileName(const Value: string);
      public
        property FileName: string read FFileName write SetFileName; 
        property OnLoad: TNotifyEvent read FOnLoad write FOnLoad; 
      end;

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    procedure TImageWeb.SetFileName(const Value: string);
    begin
      if FFileName <> Value then
      begin
        FFileName := Value;
        if TFile.Exists(FFileName) then
        begin         
          img.Bitmap.LoadFromFile (FFileName);
          if Assigned(FOnLoad) then
            FOnLoad(Self);
        end
        else
        begin
          TTask.Run(
            procedure
            begin
              // load image from Web
              // HTTP GET ...
     
              TThread.Synchronize(nil,
                procedure
                begin
                  img.Bitmap.LoadFromFile(FFileName); // Même si ici, je ferais un LoadFromStream avec le Stream ayant récupéré l'image par un HTTP GET
     
                  if Assigned(FOnLoad) then
                    FOnLoad(Self);
                end);
          end);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  17. #17
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut
    La discussion tourne drôlement

    ShaiLeTroll : Il n'y a pas opposition de ma part, plutôt une ouverture vers d'autres façon de faire et l'envie de faire avantages/inconvénients

    Paul TOTH : <<OK Boomer>> : il n'y a rien de péjoratif dans mes messages (voir ci-dessus )

    certains poussent dans ton sens, et réclament les méthodes flèches sous Delphi par exemple.
    Pas d'avis, à part une économie de clavier
    C'est aussi très utilisé dans d'autres langage : R

    c'est aussi un comportement "OK Boomer" de se préoccuper de la charge machine
    C'est une préoccupation de tout dev mais plutôt à la charge d'embarcadero, non ?


    Sans doute, dans un autre registre, ce type de dev va aussi être maltraité :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    program ArrayLinqSamples;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      System.SysUtils,
      ArrayContainer in '..\sources\ArrayContainer.pas',
      Cat in 'Cat.pas';
     
    var myPet: string;
     
    begin
      try
        myPet := TArrayContainer<TCat>
          .Create([TCat.Create('Tiger', 10, 'black', True),
            TCat.Create('Kitty', 7, 'ginger', True),
            TCat.Create('Simba', 9, 'white', True),
            TCat.Create('Barsik', 6, 'gray', False),
            TCat.Create('Sam', 8, 'white', True),
            TCat.Create('Musya', 5, 'black', True)])
          .Filter(function(const x: TCat): boolean begin exit((x.Weight > 5) and (x.HasTail)); end)
          .Map<string>(function(const x: TCat): string begin exit(x.Name); end)
          .Order()
          .FirstOrDefault(function(const x: string): boolean begin exit(x.StartsWith('S')) end);
     
        Writeln('Your pet is ' + myPet);
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 983
    Points : 25 873
    Points
    25 873
    Par défaut
    Citation Envoyé par hector94 Voir le message
    La discussion tourne drôlement

    ShaiLeTroll : Il n'y a pas opposition de ma part, plutôt une ouverture vers d'autres façon de faire et l'envie de faire avantages/inconvénients

    Paul TOTH : <<OK Boomer>> : il n'y a rien de péjoratif dans mes messages (voir ci-dessus )


    Pas d'avis, à part une économie de clavier
    C'est aussi très utilisé dans d'autres langage : R


    C'est une préoccupation de tout dev mais plutôt à la charge d'embarcadero, non ?


    Sans doute, dans un autre registre, ce type de dev va aussi être maltraité :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    program ArrayLinqSamples;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      System.SysUtils,
      ArrayContainer in '..\sources\ArrayContainer.pas',
      Cat in 'Cat.pas';
     
    var myPet: string;
     
    begin
      try
        myPet := TArrayContainer<TCat>
          .Create([TCat.Create('Tiger', 10, 'black', True),
            TCat.Create('Kitty', 7, 'ginger', True),
            TCat.Create('Simba', 9, 'white', True),
            TCat.Create('Barsik', 6, 'gray', False),
            TCat.Create('Sam', 8, 'white', True),
            TCat.Create('Musya', 5, 'black', True)])
          .Filter(function(const x: TCat): boolean begin exit((x.Weight > 5) and (x.HasTail)); end)
          .Map<string>(function(const x: TCat): string begin exit(x.Name); end)
          .Order()
          .FirstOrDefault(function(const x: string): boolean begin exit(x.StartsWith('S')) end);
     
        Writeln('Your pet is ' + myPet);
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    alors, ne prend pas mal mes commentaires, on discute pas de soucis

    mais il faut juste bien comprendre que le code que tu donnes ci-dessus pour TCat ne peux pas être extrêmement optimisé, cela restera toute une série d'appels de fonctions avec des variables temporaires qui passent de l'une à l'autre et des captures d'environnement qui créent toute une partie de code invisible et qui ont un impacte sur les ressources machines.

    moi je suis, et je revendique, d'être de la vielle école, et je ne peux m'empêcher de penser que si trois lignes plus bas du veux les animaux avec un poids < 5 sans queue, tu vas écrire ça en deux lignes mais ça va dupliquer tout le code et les captures. Alors que sur un code traditionnel plus verbeux tu évites ce problème.

    Et de toute façon c'est toujours Sam qui conduit.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  19. #19
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    alors, ne prend pas mal mes commentaires, on discute pas de soucis

    mais il faut juste bien comprendre que le code que tu donnes ci-dessus pour TCat ne peux pas être extrêmement optimisé, cela restera toute une série d'appels de fonctions avec des variables temporaires qui passent de l'une à l'autre et des captures d'environnement qui créent toute une partie de code invisible et qui ont un impacte sur les ressources machines.

    moi je suis, et je revendique, d'être de la vielle école, et je ne peux m'empêcher de penser que si trois lignes plus bas du veux les animaux avec un poids < 5 sans queue, tu vas écrire ça en deux lignes mais ça va dupliquer tout le code et les captures. Alors que sur un code traditionnel plus verbeux tu évites ce problème.

    Et de toute façon c'est toujours Sam qui conduit.
    Dans l'exemple ci-dessus on comprend pourquoi certains demandent des flèches !

    J'imagine bien qu'il y a des effets sur la sollicitation machine. quoique dans R, par exemple, ce type de programmation est aussi efficace que la méthode plus classique.
    Le compromis a atteindre est la facilité de programmation, l'adaptation aux nouveaux enseignements de la programmation et l'expérience utilisateur dans son ensemble : ux, rapidité, usage de la batterie, ...

  20. #20
    Nouveau membre du Club Avatar de hector94
    Profil pro
    Inscrit en
    octobre 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2007
    Messages : 42
    Points : 34
    Points
    34
    Par défaut
    ShaiLeTroll

    Pascal est un langage de programmation impératif qui, conçu pour l'enseignement, se caractérise par une syntaxe claire, rigoureuse et facilitant la structuration des programmes.
    Ce n'est plus systématiquement utilisé pour l'enseignement, je crois. Pour le reste ce sont des vérités incontestables.
    Ce qui est incontestable aussi, c'est qu'il n'y a pas bcp de nouveaux dev attirés par Delphi et c'est dommage !
    Ce qui est surement utile est de trouver pourquoi (peut-être uniquement parce qu'il n'est plus dans les cursus) et de proposer des moyens d'accrocher des dev.
    Peut-être le "design" de la programmation ?

    Cela n'a rien de laborieux, c'est même un plaisir d'avoir un code d'utilisation simple pour masquer un fonctionnement complexe
    De ma pratique, je ne vois pas d'opposition à ce principe

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/09/2016, 19h04
  2. Réponses: 7
    Dernier message: 10/08/2016, 10h24
  3. [Batch] Impossible d'afficher le symbole >
    Par LeoBeutel dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 15/03/2015, 16h32
  4. Réponses: 2
    Dernier message: 20/06/2014, 15h42
  5. CreateProcess (impossible de gérer le symbole >
    Par borgirz dans le forum Windows
    Réponses: 4
    Dernier message: 03/06/2004, 10h53

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